@pluv/react 0.25.4 → 0.26.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/react@0.25.4 build /home/runner/work/pluv/pluv/packages/react
2
+ > @pluv/react@0.26.0 build /home/runner/work/pluv/pluv/packages/react
3
3
  > tsup src/index.ts --format esm,cjs --dts --external react
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -8,11 +8,11 @@
8
8
  CLI Target: es6
9
9
  ESM Build start
10
10
  CJS Build start
11
- ESM dist/index.mjs 11.87 KB
12
- ESM ⚡️ Build success in 124ms
13
- CJS dist/index.js 14.27 KB
14
- CJS ⚡️ Build success in 125ms
11
+ CJS dist/index.js 14.30 KB
12
+ CJS ⚡️ Build success in 127ms
13
+ ESM dist/index.mjs 11.89 KB
14
+ ESM ⚡️ Build success in 128ms
15
15
  DTS Build start
16
- DTS ⚡️ Build success in 4984ms
17
- DTS dist/index.d.mts 5.17 KB
18
- DTS dist/index.d.ts 5.17 KB
16
+ DTS ⚡️ Build success in 4697ms
17
+ DTS dist/index.d.mts 5.50 KB
18
+ DTS dist/index.d.ts 5.50 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,61 @@
1
1
  # @pluv/react
2
2
 
3
+ ## 0.26.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 19e5dda: **BREAKING**
8
+ Update `authEndpoint` and `wsEndpoint` to now use a parameterized object that passes through additional data via a `metadata` property.
9
+
10
+ ```tsx
11
+ // Before
12
+
13
+ import { env } from "./env";
14
+ import type { ioServer } from "./server";
15
+
16
+ const client = createClient<typeof ioServer>({
17
+ authEndpoint: (room: string) => `${env.API_URL}}/room/${room}`,
18
+ wsEndpoint: (room: string) => `${env.WS_URL}/room/${room}`,
19
+ });
20
+
21
+ // After
22
+
23
+ const client = createClient<
24
+ typeof ioServer,
25
+ // Optional: You can specify types for metadata here. This is useful for Cloudflare Pages
26
+ { apiUrl: string; wsUrl: string }
27
+ >({
28
+ authEndpoint: ({ metadata, room }) => `${metadata.apiUrl}}/room/${room}`,
29
+ wsEndpoint: ({ metadata, room }) => `${{ metadata.wsUrl }}/room/${room}`,
30
+ });
31
+
32
+ client.createRoom("my-room", {
33
+ // This property exists when the `metadata` generic type is defined above
34
+ metadata: {
35
+ apiUrl: "https://example.com/api",
36
+ wsUrl: "wss://example.com/api",
37
+ },
38
+ // ...
39
+ });
40
+
41
+ <PluvRoomProvider
42
+ // This property exists when the `metadata` generic type is defined above
43
+ metadata={{
44
+ apiUrl: "https://example.com/api",
45
+ wsUrl: "wss://example.com/api",
46
+ }}
47
+ >
48
+ {/* ... */}
49
+ </PluvRoomProvider>
50
+ ```
51
+
52
+ ### Patch Changes
53
+
54
+ - Updated dependencies [19e5dda]
55
+ - @pluv/client@0.26.0
56
+ - @pluv/crdt@0.26.0
57
+ - @pluv/types@0.26.0
58
+
3
59
  ## 0.25.4
4
60
 
5
61
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -6,8 +6,8 @@ import { IOLike, JsonObject, InputZodLike, Id, InferIOOutput, IOEventMessage, In
6
6
  export { BaseUser, EventMessage, EventRecord, IOEventMessage } from '@pluv/types';
7
7
  import { FC, Dispatch, ReactNode } from 'react';
8
8
 
9
- type CreateRoomBundleOptions<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}> = {
10
- addons?: readonly PluvRoomAddon<TIO, TPresence, TStorage>[];
9
+ type CreateRoomBundleOptions<TIO extends IOLike, TMetadata extends JsonObject = {}, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}> = {
10
+ addons?: readonly PluvRoomAddon<TIO, TMetadata, TPresence, TStorage>[];
11
11
  initialStorage?: AbstractCrdtDocFactory<TStorage>;
12
12
  presence?: InputZodLike<TPresence>;
13
13
  };
@@ -23,10 +23,14 @@ type BaseRoomProviderProps<TPresence extends JsonObject, TStorage extends Record
23
23
  type MockedRoomProviderProps<TIO extends IOLike, TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>> = BaseRoomProviderProps<TPresence, TStorage> & {
24
24
  events?: MockedRoomEvents<TIO>;
25
25
  };
26
- type PluvRoomProviderProps<TIO extends IOLike, TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>> = BaseRoomProviderProps<TPresence, TStorage> & {
26
+ type PluvRoomProviderProps<TIO extends IOLike, TMetadata extends JsonObject, TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>> = BaseRoomProviderProps<TPresence, TStorage> & {
27
27
  debug?: boolean | PluvRoomDebug<TIO>;
28
28
  onAuthorizationFail?: (error: Error) => void;
29
- };
29
+ } & (keyof TMetadata extends never ? {
30
+ metadata?: undefined;
31
+ } : {
32
+ metadata: TMetadata;
33
+ });
30
34
  interface SubscriptionHookOptions<T extends unknown> {
31
35
  isEqual?: (a: T, b: T) => boolean;
32
36
  }
@@ -39,9 +43,9 @@ type EventProxy<TIO extends IOLike> = {
39
43
  useEvent: (callback: (data: Id<IOEventMessage<TIO, event>>) => void) => void;
40
44
  };
41
45
  };
42
- interface CreateRoomBundle<TIO extends IOLike, TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>> {
46
+ interface CreateRoomBundle<TIO extends IOLike, TMetadata extends JsonObject, TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>> {
43
47
  MockedRoomProvider: FC<MockedRoomProviderProps<TIO, TPresence, TStorage>>;
44
- PluvRoomProvider: FC<PluvRoomProviderProps<TIO, TPresence, TStorage>>;
48
+ PluvRoomProvider: FC<PluvRoomProviderProps<TIO, TMetadata, TPresence, TStorage>>;
45
49
  event: EventProxy<TIO>;
46
50
  useBroadcast: () => BroadcastProxy<TIO>;
47
51
  useCanRedo: () => boolean;
@@ -59,16 +63,16 @@ interface CreateRoomBundle<TIO extends IOLike, TPresence extends JsonObject, TSt
59
63
  useTransact: () => (fn: (storage: TStorage) => void, origin?: string) => void;
60
64
  useUndo: () => () => void;
61
65
  }
62
- type InferRoomStorage<TRoomBundle extends CreateRoomBundle<any, any, any>> = TRoomBundle extends CreateRoomBundle<any, any, infer IStorage> ? IStorage : never;
66
+ type InferRoomStorage<TRoomBundle extends CreateRoomBundle<any, any, any, any>> = TRoomBundle extends CreateRoomBundle<any, any, any, infer IStorage> ? IStorage : never;
63
67
 
64
68
  interface PluvProviderProps {
65
69
  children?: ReactNode;
66
70
  }
67
- interface CreateBundle<TIO extends IOLike> {
68
- createRoomBundle: <TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}>(options: CreateRoomBundleOptions<TIO, TPresence, TStorage>) => CreateRoomBundle<TIO, TPresence, TStorage>;
71
+ interface CreateBundle<TIO extends IOLike, TMetadata extends JsonObject> {
72
+ createRoomBundle: <TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}>(options: CreateRoomBundleOptions<TIO, TMetadata, TPresence, TStorage>) => CreateRoomBundle<TIO, TMetadata, TPresence, TStorage>;
69
73
  PluvProvider: FC<PluvProviderProps>;
70
- useClient: () => PluvClient<TIO>;
74
+ useClient: () => PluvClient<TIO, TMetadata>;
71
75
  }
72
- declare const createBundle: <TIO extends IOLike>(client: PluvClient<TIO>) => CreateBundle<TIO>;
76
+ declare const createBundle: <TIO extends IOLike, TMetadata extends JsonObject>(client: PluvClient<TIO, TMetadata>) => CreateBundle<TIO, TMetadata>;
73
77
 
74
78
  export { type CreateBundle, type CreateRoomBundle, type CreateRoomBundleOptions, type InferRoomStorage, type PluvProviderProps, type PluvRoomProviderProps, type SubscriptionHookOptions, createBundle };
package/dist/index.d.ts CHANGED
@@ -6,8 +6,8 @@ import { IOLike, JsonObject, InputZodLike, Id, InferIOOutput, IOEventMessage, In
6
6
  export { BaseUser, EventMessage, EventRecord, IOEventMessage } from '@pluv/types';
7
7
  import { FC, Dispatch, ReactNode } from 'react';
8
8
 
9
- type CreateRoomBundleOptions<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}> = {
10
- addons?: readonly PluvRoomAddon<TIO, TPresence, TStorage>[];
9
+ type CreateRoomBundleOptions<TIO extends IOLike, TMetadata extends JsonObject = {}, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}> = {
10
+ addons?: readonly PluvRoomAddon<TIO, TMetadata, TPresence, TStorage>[];
11
11
  initialStorage?: AbstractCrdtDocFactory<TStorage>;
12
12
  presence?: InputZodLike<TPresence>;
13
13
  };
@@ -23,10 +23,14 @@ type BaseRoomProviderProps<TPresence extends JsonObject, TStorage extends Record
23
23
  type MockedRoomProviderProps<TIO extends IOLike, TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>> = BaseRoomProviderProps<TPresence, TStorage> & {
24
24
  events?: MockedRoomEvents<TIO>;
25
25
  };
26
- type PluvRoomProviderProps<TIO extends IOLike, TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>> = BaseRoomProviderProps<TPresence, TStorage> & {
26
+ type PluvRoomProviderProps<TIO extends IOLike, TMetadata extends JsonObject, TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>> = BaseRoomProviderProps<TPresence, TStorage> & {
27
27
  debug?: boolean | PluvRoomDebug<TIO>;
28
28
  onAuthorizationFail?: (error: Error) => void;
29
- };
29
+ } & (keyof TMetadata extends never ? {
30
+ metadata?: undefined;
31
+ } : {
32
+ metadata: TMetadata;
33
+ });
30
34
  interface SubscriptionHookOptions<T extends unknown> {
31
35
  isEqual?: (a: T, b: T) => boolean;
32
36
  }
@@ -39,9 +43,9 @@ type EventProxy<TIO extends IOLike> = {
39
43
  useEvent: (callback: (data: Id<IOEventMessage<TIO, event>>) => void) => void;
40
44
  };
41
45
  };
42
- interface CreateRoomBundle<TIO extends IOLike, TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>> {
46
+ interface CreateRoomBundle<TIO extends IOLike, TMetadata extends JsonObject, TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>> {
43
47
  MockedRoomProvider: FC<MockedRoomProviderProps<TIO, TPresence, TStorage>>;
44
- PluvRoomProvider: FC<PluvRoomProviderProps<TIO, TPresence, TStorage>>;
48
+ PluvRoomProvider: FC<PluvRoomProviderProps<TIO, TMetadata, TPresence, TStorage>>;
45
49
  event: EventProxy<TIO>;
46
50
  useBroadcast: () => BroadcastProxy<TIO>;
47
51
  useCanRedo: () => boolean;
@@ -59,16 +63,16 @@ interface CreateRoomBundle<TIO extends IOLike, TPresence extends JsonObject, TSt
59
63
  useTransact: () => (fn: (storage: TStorage) => void, origin?: string) => void;
60
64
  useUndo: () => () => void;
61
65
  }
62
- type InferRoomStorage<TRoomBundle extends CreateRoomBundle<any, any, any>> = TRoomBundle extends CreateRoomBundle<any, any, infer IStorage> ? IStorage : never;
66
+ type InferRoomStorage<TRoomBundle extends CreateRoomBundle<any, any, any, any>> = TRoomBundle extends CreateRoomBundle<any, any, any, infer IStorage> ? IStorage : never;
63
67
 
64
68
  interface PluvProviderProps {
65
69
  children?: ReactNode;
66
70
  }
67
- interface CreateBundle<TIO extends IOLike> {
68
- createRoomBundle: <TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}>(options: CreateRoomBundleOptions<TIO, TPresence, TStorage>) => CreateRoomBundle<TIO, TPresence, TStorage>;
71
+ interface CreateBundle<TIO extends IOLike, TMetadata extends JsonObject> {
72
+ createRoomBundle: <TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}>(options: CreateRoomBundleOptions<TIO, TMetadata, TPresence, TStorage>) => CreateRoomBundle<TIO, TMetadata, TPresence, TStorage>;
69
73
  PluvProvider: FC<PluvProviderProps>;
70
- useClient: () => PluvClient<TIO>;
74
+ useClient: () => PluvClient<TIO, TMetadata>;
71
75
  }
72
- declare const createBundle: <TIO extends IOLike>(client: PluvClient<TIO>) => CreateBundle<TIO>;
76
+ declare const createBundle: <TIO extends IOLike, TMetadata extends JsonObject>(client: PluvClient<TIO, TMetadata>) => CreateBundle<TIO, TMetadata>;
73
77
 
74
78
  export { type CreateBundle, type CreateRoomBundle, type CreateRoomBundleOptions, type InferRoomStorage, type PluvProviderProps, type PluvRoomProviderProps, type SubscriptionHookOptions, createBundle };
package/dist/index.js CHANGED
@@ -130,7 +130,7 @@ var createRoomBundle = (client, options) => {
130
130
  });
131
131
  MockedRoomProvider.displayName = "MockedRoomProvider";
132
132
  const PluvRoomProvider = (0, import_react4.memo)((props) => {
133
- const { children, debug, initialPresence, initialStorage, onAuthorizationFail, room: _room } = props;
133
+ const { children, debug, initialPresence, initialStorage, metadata, onAuthorizationFail, room: _room } = props;
134
134
  const rerender = useRerender();
135
135
  const { room: mockedRoom } = (0, import_react4.useContext)(MockedRoomContext);
136
136
  const [room] = (0, import_react4.useState)(() => {
@@ -139,6 +139,7 @@ var createRoomBundle = (client, options) => {
139
139
  debug,
140
140
  initialPresence,
141
141
  initialStorage: typeof initialStorage === "function" ? _initialStorage.getFactory(initialStorage) : _initialStorage,
142
+ metadata,
142
143
  presence: options.presence,
143
144
  onAuthorizationFail
144
145
  });
package/dist/index.mjs CHANGED
@@ -94,7 +94,7 @@ var createRoomBundle = (client, options) => {
94
94
  });
95
95
  MockedRoomProvider.displayName = "MockedRoomProvider";
96
96
  const PluvRoomProvider = memo((props) => {
97
- const { children, debug, initialPresence, initialStorage, onAuthorizationFail, room: _room } = props;
97
+ const { children, debug, initialPresence, initialStorage, metadata, onAuthorizationFail, room: _room } = props;
98
98
  const rerender = useRerender();
99
99
  const { room: mockedRoom } = useContext(MockedRoomContext);
100
100
  const [room] = useState3(() => {
@@ -103,6 +103,7 @@ var createRoomBundle = (client, options) => {
103
103
  debug,
104
104
  initialPresence,
105
105
  initialStorage: typeof initialStorage === "function" ? _initialStorage.getFactory(initialStorage) : _initialStorage,
106
+ metadata,
106
107
  presence: options.presence,
107
108
  onAuthorizationFail
108
109
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pluv/react",
3
- "version": "0.25.4",
3
+ "version": "0.26.0",
4
4
  "description": "@pluv/client React.js bindings",
5
5
  "author": "leedavidcs",
6
6
  "license": "MIT",
@@ -18,9 +18,9 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "fast-deep-equal": "^3.1.3",
21
- "@pluv/client": "^0.25.4",
22
- "@pluv/crdt": "^0.25.4",
23
- "@pluv/types": "^0.25.4"
21
+ "@pluv/client": "^0.26.0",
22
+ "@pluv/crdt": "^0.26.0",
23
+ "@pluv/types": "^0.26.0"
24
24
  },
25
25
  "peerDependencies": {
26
26
  "@types/react": "^18.0.0",
@@ -32,8 +32,8 @@
32
32
  "react": "^18.3.1",
33
33
  "tsup": "^8.2.4",
34
34
  "typescript": "^5.5.4",
35
- "@pluv/tsconfig": "^0.25.4",
36
- "eslint-config-pluv": "^0.25.4"
35
+ "@pluv/tsconfig": "^0.26.0",
36
+ "eslint-config-pluv": "^0.26.0"
37
37
  },
38
38
  "scripts": {
39
39
  "build": "tsup src/index.ts --format esm,cjs --dts --external react",
@@ -10,20 +10,22 @@ export interface PluvProviderProps {
10
10
  children?: ReactNode;
11
11
  }
12
12
 
13
- export interface CreateBundle<TIO extends IOLike> {
13
+ export interface CreateBundle<TIO extends IOLike, TMetadata extends JsonObject> {
14
14
  // factories
15
15
  createRoomBundle: <TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}>(
16
- options: CreateRoomBundleOptions<TIO, TPresence, TStorage>,
17
- ) => CreateRoomBundle<TIO, TPresence, TStorage>;
16
+ options: CreateRoomBundleOptions<TIO, TMetadata, TPresence, TStorage>,
17
+ ) => CreateRoomBundle<TIO, TMetadata, TPresence, TStorage>;
18
18
 
19
19
  // components
20
20
  PluvProvider: FC<PluvProviderProps>;
21
21
 
22
22
  // hooks
23
- useClient: () => PluvClient<TIO>;
23
+ useClient: () => PluvClient<TIO, TMetadata>;
24
24
  }
25
25
 
26
- export const createBundle = <TIO extends IOLike>(client: PluvClient<TIO>): CreateBundle<TIO> => {
26
+ export const createBundle = <TIO extends IOLike, TMetadata extends JsonObject>(
27
+ client: PluvClient<TIO, TMetadata>,
28
+ ): CreateBundle<TIO, TMetadata> => {
27
29
  /**
28
30
  * !HACK
29
31
  * @description We'll let the context error out if client is not provided,
@@ -31,7 +33,7 @@ export const createBundle = <TIO extends IOLike>(client: PluvClient<TIO>): Creat
31
33
  * @author leedavidcs
32
34
  * @date October 27, 2022
33
35
  */
34
- const PluvContext = createContext<PluvClient<any>>(null as any);
36
+ const PluvContext = createContext<PluvClient<TIO, TMetadata>>(null as any);
35
37
 
36
38
  const PluvProvider = memo<PluvProviderProps>((props) => {
37
39
  const { children } = props;
@@ -41,14 +43,14 @@ export const createBundle = <TIO extends IOLike>(client: PluvClient<TIO>): Creat
41
43
 
42
44
  PluvProvider.displayName = "PluvProvider";
43
45
 
44
- const useClient = (): PluvClient<TIO> => useContext(PluvContext);
46
+ const useClient = (): PluvClient<TIO, TMetadata> => useContext(PluvContext);
45
47
 
46
48
  const createRoomBundle = <
47
49
  TPresence extends JsonObject = {},
48
50
  TStorage extends Record<string, CrdtType<any, any>> = {},
49
51
  >(
50
- options: CreateRoomBundleOptions<TIO, TPresence, TStorage>,
51
- ): CreateRoomBundle<TIO, TPresence, TStorage> => _createRoomBundle(client, options);
52
+ options: CreateRoomBundleOptions<TIO, TMetadata, TPresence, TStorage>,
53
+ ): CreateRoomBundle<TIO, TMetadata, TPresence, TStorage> => _createRoomBundle(client, options);
52
54
 
53
55
  return {
54
56
  createRoomBundle,
@@ -5,6 +5,7 @@ import type {
5
5
  PluvRoom,
6
6
  PluvRoomAddon,
7
7
  PluvRoomDebug,
8
+ PluvRoomOptions,
8
9
  UserInfo,
9
10
  WebSocketConnection,
10
11
  } from "@pluv/client";
@@ -19,10 +20,11 @@ import { identity, shallowArrayEqual, useRerender, useSyncExternalStoreWithSelec
19
20
 
20
21
  export type CreateRoomBundleOptions<
21
22
  TIO extends IOLike,
23
+ TMetadata extends JsonObject = {},
22
24
  TPresence extends JsonObject = {},
23
25
  TStorage extends Record<string, CrdtType<any, any>> = {},
24
26
  > = {
25
- addons?: readonly PluvRoomAddon<TIO, TPresence, TStorage>[];
27
+ addons?: readonly PluvRoomAddon<TIO, TMetadata, TPresence, TStorage>[];
26
28
  initialStorage?: AbstractCrdtDocFactory<TStorage>;
27
29
  presence?: InputZodLike<TPresence>;
28
30
  };
@@ -43,12 +45,13 @@ export type MockedRoomProviderProps<
43
45
 
44
46
  export type PluvRoomProviderProps<
45
47
  TIO extends IOLike,
48
+ TMetadata extends JsonObject,
46
49
  TPresence extends JsonObject,
47
50
  TStorage extends Record<string, CrdtType<any, any>>,
48
51
  > = BaseRoomProviderProps<TPresence, TStorage> & {
49
52
  debug?: boolean | PluvRoomDebug<TIO>;
50
53
  onAuthorizationFail?: (error: Error) => void;
51
- };
54
+ } & (keyof TMetadata extends never ? { metadata?: undefined } : { metadata: TMetadata });
52
55
 
53
56
  export interface SubscriptionHookOptions<T extends unknown> {
54
57
  isEqual?: (a: T, b: T) => boolean;
@@ -73,12 +76,13 @@ export type EventProxy<TIO extends IOLike> = {
73
76
 
74
77
  export interface CreateRoomBundle<
75
78
  TIO extends IOLike,
79
+ TMetadata extends JsonObject,
76
80
  TPresence extends JsonObject,
77
81
  TStorage extends Record<string, CrdtType<any, any>>,
78
82
  > {
79
83
  // components
80
84
  MockedRoomProvider: FC<MockedRoomProviderProps<TIO, TPresence, TStorage>>;
81
- PluvRoomProvider: FC<PluvRoomProviderProps<TIO, TPresence, TStorage>>;
85
+ PluvRoomProvider: FC<PluvRoomProviderProps<TIO, TMetadata, TPresence, TStorage>>;
82
86
 
83
87
  // proxies
84
88
  event: EventProxy<TIO>;
@@ -124,17 +128,18 @@ export interface CreateRoomBundle<
124
128
  useUndo: () => () => void;
125
129
  }
126
130
 
127
- export type InferRoomStorage<TRoomBundle extends CreateRoomBundle<any, any, any>> =
128
- TRoomBundle extends CreateRoomBundle<any, any, infer IStorage> ? IStorage : never;
131
+ export type InferRoomStorage<TRoomBundle extends CreateRoomBundle<any, any, any, any>> =
132
+ TRoomBundle extends CreateRoomBundle<any, any, any, infer IStorage> ? IStorage : never;
129
133
 
130
134
  export const createRoomBundle = <
131
135
  TIO extends IOLike,
136
+ TMetadata extends JsonObject = {},
132
137
  TPresence extends JsonObject = {},
133
138
  TStorage extends Record<string, CrdtType<any, any>> = {},
134
139
  >(
135
- client: PluvClient<TIO>,
136
- options: CreateRoomBundleOptions<TIO, TPresence, TStorage>,
137
- ): CreateRoomBundle<TIO, TPresence, TStorage> => {
140
+ client: PluvClient<TIO, TMetadata>,
141
+ options: CreateRoomBundleOptions<TIO, TMetadata, TPresence, TStorage>,
142
+ ): CreateRoomBundle<TIO, TMetadata, TPresence, TStorage> => {
138
143
  const _initialStorage = (options.initialStorage ?? noop.doc()) as AbstractCrdtDocFactory<TStorage>;
139
144
 
140
145
  /**
@@ -172,22 +177,23 @@ export const createRoomBundle = <
172
177
 
173
178
  MockedRoomProvider.displayName = "MockedRoomProvider";
174
179
 
175
- const PluvRoomProvider = memo<PluvRoomProviderProps<TIO, TPresence, TStorage>>((props) => {
176
- const { children, debug, initialPresence, initialStorage, onAuthorizationFail, room: _room } = props;
180
+ const PluvRoomProvider = memo<PluvRoomProviderProps<TIO, TMetadata, TPresence, TStorage>>((props) => {
181
+ const { children, debug, initialPresence, initialStorage, metadata, onAuthorizationFail, room: _room } = props;
177
182
 
178
183
  const rerender = useRerender();
179
184
  const { room: mockedRoom } = useContext(MockedRoomContext);
180
185
 
181
- const [room] = useState<PluvRoom<TIO, TPresence, TStorage>>(() => {
186
+ const [room] = useState<PluvRoom<TIO, TMetadata, TPresence, TStorage>>(() => {
182
187
  return client.createRoom<TPresence, TStorage>(_room, {
183
188
  addons: options.addons,
184
189
  debug,
185
190
  initialPresence,
186
191
  initialStorage:
187
192
  typeof initialStorage === "function" ? _initialStorage.getFactory(initialStorage) : _initialStorage,
193
+ metadata,
188
194
  presence: options.presence,
189
195
  onAuthorizationFail,
190
- });
196
+ } as PluvRoomOptions<TIO, TMetadata, TPresence, TStorage>);
191
197
  });
192
198
 
193
199
  useEffect(() => {