@pluv/react 1.0.1 → 2.0.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@1.0.1 build /home/runner/work/pluv/pluv/packages/react
2
+ > @pluv/react@2.0.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 16.71 KB
12
- ESM ⚡️ Build success in 109ms
13
- CJS dist/index.js 19.09 KB
14
- CJS ⚡️ Build success in 113ms
11
+ ESM dist/index.mjs 16.73 KB
12
+ ESM ⚡️ Build success in 107ms
13
+ CJS dist/index.js 19.10 KB
14
+ CJS ⚡️ Build success in 107ms
15
15
  DTS Build start
16
- DTS ⚡️ Build success in 5971ms
17
- DTS dist/index.d.mts 5.54 KB
18
- DTS dist/index.d.ts 5.54 KB
16
+ DTS ⚡️ Build success in 6197ms
17
+ DTS dist/index.d.mts 5.70 KB
18
+ DTS dist/index.d.ts 5.70 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,70 @@
1
1
  # @pluv/react
2
2
 
3
+ ## 2.0.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 5cec54a: **Deprecated** Declaring top-level types on your CRDT storage via the `yjs` or `loro` utility (e.g. `yjs.array` or `loro.list`) for the `initialStorage` prop on `PluvRoomProvider` is now deprecated, to be removed in the next major release (v2). Continuing to use the `yjs` or `loro` utilities to declare top-level types will log a warning to your console while in development mode (i.e. when `process.env.NODE_ENV === "development"`). To declare top-level types, you should now use the builder type exposed in the `initialStorage` function. See the example below:
8
+
9
+ ```tsx
10
+ import { yjs } from "@pluv/crdt-yjs";
11
+
12
+ // Before
13
+ <PluvRoomProvider
14
+ room="example-room"
15
+ initialStorage={() => ({
16
+ // Using the `yjs` or `loro` utility (in this case `yjs.map`) when
17
+ // declaring top-level types is now deprecated
18
+ topType: yjs.map([
19
+ ["key1", yjs.text("")],
20
+ ["key2", yjs.text("")],
21
+ ]),
22
+ })}
23
+ >
24
+ <div />
25
+ </PluvRoomProvider>
26
+
27
+ // After
28
+ <PluvRoomProvider
29
+ room="example-room"
30
+ initialStorage={(t) => ({
31
+ // Top-level properties must now use the builder (in this case `t`).
32
+ // This effectively calls `yjs.getMap("topType")` to instantiate the type on
33
+ // the root document.
34
+ // This simply returns the native Yjs shared-types (e.g. Y.Map), which
35
+ // allows you operate on your yjs shared-typess in a more native way.
36
+ topType: t.map("topType", [
37
+ // Declaring nested types should continue to use the `yjs` utilities
38
+ // you've used before
39
+ ["key1", yjs.text("")],
40
+ ["key2", yjs.text("")],
41
+ ]),
42
+ })}
43
+ >
44
+ <div />
45
+ </PluvRoomProvider>
46
+ ```
47
+
48
+ The functions on the builder type calls the native yjs shared-type (or loro container type) instantiating methods and returns the native types (e.g. `t.map("topType")` is simply just a `Y.Doc.getMap("topType")`) call under the hood. This allows you to declare your type in a more yjs-native and predictable way, and enables declaring more complex initial storage states if needed.
49
+
50
+ ### Patch Changes
51
+
52
+ - Updated dependencies [047a1d8]
53
+ - Updated dependencies [0806212]
54
+ - Updated dependencies [3a34dbb]
55
+ - @pluv/client@2.0.0
56
+ - @pluv/types@2.0.0
57
+ - @pluv/crdt@2.0.0
58
+
59
+ ## 1.0.2
60
+
61
+ ### Patch Changes
62
+
63
+ - Updated dependencies [d87159c]
64
+ - @pluv/client@1.0.2
65
+ - @pluv/crdt@1.0.2
66
+ - @pluv/types@1.0.2
67
+
3
68
  ## 1.0.1
4
69
 
5
70
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -1,25 +1,25 @@
1
- import { PluvRouterEventConfig, PluvClient, PluvRoomAddon, PluvRouter, MockedRoomEvents, MergeEvents, PluvRoomDebug, WebSocketConnection, UserInfo, AbstractRoom } from '@pluv/client';
2
- import { CrdtType, AbstractCrdtDoc, InferCrdtJson } from '@pluv/crdt';
3
- import { IOLike, JsonObject, MaybePromise, InferIOOutput, Id, IOEventMessage, InferIOInput } from '@pluv/types';
1
+ import { PluvRouterEventConfig, PluvClient, PluvRoomAddon, PluvRouter, MockedRoomEvents, MergeEvents, PluvRoomDebug, WebSocketConnection, UserInfo } from '@pluv/client';
2
+ import { AbstractCrdtDocFactory, NoopCrdtDocFactory, InferStorage, InferInitialStorageFn, InferCrdtJson } from '@pluv/crdt';
3
+ import { IOLike, JsonObject, MaybePromise, InferIOOutput, Id, IOEventMessage, InferIOInput, CrdtDocLike, RoomLike } from '@pluv/types';
4
4
  import { FC, ReactNode, Dispatch } from 'react';
5
5
 
6
6
  interface PluvProviderProps {
7
7
  children?: ReactNode;
8
8
  }
9
- type BaseRoomProviderProps<TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>> = {
9
+ type BaseRoomProviderProps<TPresence extends JsonObject, TCrdt extends AbstractCrdtDocFactory<any>> = {
10
10
  children?: ReactNode;
11
- initialStorage?: keyof TStorage extends never ? never : () => TStorage;
11
+ initialStorage?: keyof InferStorage<TCrdt> extends never ? never : InferInitialStorageFn<TCrdt>;
12
12
  room: string;
13
13
  } & (keyof TPresence extends never ? {
14
14
  initialPresence?: never;
15
15
  } : {
16
16
  initialPresence: TPresence;
17
17
  });
18
- type MockedRoomProviderProps<TIO extends IOLike, TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>, TEvents extends PluvRouterEventConfig<TIO, TPresence, TStorage> = {}> = BaseRoomProviderProps<TPresence, TStorage> & {
18
+ type MockedRoomProviderProps<TIO extends IOLike, TPresence extends JsonObject, TCrdt extends AbstractCrdtDocFactory<any>, TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {}> = BaseRoomProviderProps<TPresence, TCrdt> & {
19
19
  events?: MockedRoomEvents<MergeEvents<TEvents, TIO>>;
20
20
  };
21
21
  type MetadataGetter<TMetadata extends JsonObject> = TMetadata | (() => MaybePromise<TMetadata>);
22
- type PluvRoomProviderProps<TIO extends IOLike<any, any>, TMetadata extends JsonObject, TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>> = BaseRoomProviderProps<TPresence, TStorage> & {
22
+ type PluvRoomProviderProps<TIO extends IOLike<any, any>, TMetadata extends JsonObject, TPresence extends JsonObject, TCrdt extends AbstractCrdtDocFactory<any>> = BaseRoomProviderProps<TPresence, TCrdt> & {
23
23
  connect?: boolean;
24
24
  debug?: boolean | PluvRoomDebug<TIO>;
25
25
  onAuthorizationFail?: (error: Error) => void;
@@ -40,32 +40,32 @@ type EventProxy<TIO extends IOLike> = {
40
40
  useEvent: (callback: (data: Id<IOEventMessage<TIO, event>>) => void) => void;
41
41
  };
42
42
  };
43
- interface CreateBundle<TIO extends IOLike, TMetadata extends JsonObject, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}, TEvents extends PluvRouterEventConfig<TIO, TPresence, TStorage> = {}> {
44
- MockedRoomProvider: FC<MockedRoomProviderProps<TIO, TPresence, TStorage>>;
43
+ interface CreateBundle<TIO extends IOLike, TMetadata extends JsonObject, TPresence extends JsonObject = {}, TCrdt extends AbstractCrdtDocFactory<any> = NoopCrdtDocFactory, TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {}> {
44
+ MockedRoomProvider: FC<MockedRoomProviderProps<TIO, TPresence, TCrdt>>;
45
45
  PluvProvider: FC<PluvProviderProps>;
46
- PluvRoomProvider: FC<PluvRoomProviderProps<TIO, TMetadata, TPresence, TStorage>>;
46
+ PluvRoomProvider: FC<PluvRoomProviderProps<TIO, TMetadata, TPresence, TCrdt>>;
47
47
  event: EventProxy<MergeEvents<TEvents, TIO>>;
48
48
  useBroadcast: () => BroadcastProxy<MergeEvents<TEvents, TIO>>;
49
49
  useCanRedo: () => boolean;
50
50
  useCanUndo: () => boolean;
51
- useClient: () => PluvClient<TIO, TPresence, TStorage, TMetadata>;
51
+ useClient: () => PluvClient<TIO, TPresence, TCrdt, TMetadata>;
52
52
  useConnection: <T extends unknown = WebSocketConnection>(selector: (connection: WebSocketConnection) => T, options?: SubscriptionHookOptions<Id<T>>) => Id<T>;
53
- useDoc: () => AbstractCrdtDoc<TStorage>;
53
+ useDoc: () => CrdtDocLike<InferStorage<TCrdt>>;
54
54
  useEvent: <TType extends keyof InferIOOutput<MergeEvents<TEvents, TIO>>>(type: TType, callback: (data: Id<IOEventMessage<MergeEvents<TEvents, TIO>, TType>>) => void) => void;
55
55
  useMyPresence: <T extends unknown = TPresence>(selector?: (myPresence: TPresence) => T, options?: SubscriptionHookOptions<Id<T> | null>) => [myPresence: Id<T>, updateMyPresence: Dispatch<UpdateMyPresenceAction<TPresence>>];
56
56
  useMyself: <T extends unknown = UserInfo<TIO, TPresence>>(selector?: (myself: Id<UserInfo<TIO, TPresence>>) => T, options?: SubscriptionHookOptions<Id<T> | null>) => Id<T> | null;
57
57
  useOther: <T extends unknown = UserInfo<TIO, TPresence>>(connectionId: string, selector?: (other: UserInfo<TIO, TPresence>) => T, options?: SubscriptionHookOptions<T | null>) => T | null;
58
58
  useOthers: <T extends unknown = readonly UserInfo<TIO, TPresence>[]>(selector?: (other: readonly Id<UserInfo<TIO, TPresence>>[]) => T, options?: SubscriptionHookOptions<T>) => T;
59
59
  useRedo: () => () => void;
60
- useRoom: () => AbstractRoom<TIO, TPresence, TStorage>;
61
- useStorage: <TKey extends keyof TStorage, TData extends unknown = InferCrdtJson<TStorage[TKey]>>(key: TKey, selector?: (data: InferCrdtJson<TStorage[TKey]>) => TData, options?: SubscriptionHookOptions<TData | null>) => [data: TData | null, sharedType: TStorage[TKey] | null];
62
- useTransact: () => (fn: (storage: TStorage) => void, origin?: string) => void;
60
+ useRoom: () => RoomLike<TIO, TPresence, InferStorage<TCrdt>>;
61
+ useStorage: <TKey extends keyof InferStorage<TCrdt>, TData extends unknown = InferCrdtJson<InferStorage<TCrdt>[TKey]>>(key: TKey, selector?: (data: InferCrdtJson<InferStorage<TCrdt>[TKey]>) => TData, options?: SubscriptionHookOptions<TData | null>) => [data: TData | null, sharedType: InferStorage<TCrdt>[TKey] | null];
62
+ useTransact: () => (fn: (storage: InferStorage<TCrdt>) => void, origin?: string) => void;
63
63
  useUndo: () => () => void;
64
64
  }
65
- type CreateBundleOptions<TIO extends IOLike, TMetadata extends JsonObject = {}, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}, TEvents extends PluvRouterEventConfig<TIO, TPresence, TStorage> = {}> = {
66
- addons?: readonly PluvRoomAddon<TIO, TMetadata, TPresence, TStorage>[];
67
- router?: PluvRouter<TIO, TPresence, TStorage, TEvents>;
65
+ type CreateBundleOptions<TIO extends IOLike, TMetadata extends JsonObject = {}, TPresence extends JsonObject = {}, TCrdt extends AbstractCrdtDocFactory<any> = NoopCrdtDocFactory, TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {}> = {
66
+ addons?: readonly PluvRoomAddon<TIO, TMetadata, TPresence, TCrdt>[];
67
+ router?: PluvRouter<TIO, TPresence, InferStorage<TCrdt>, TEvents>;
68
68
  };
69
- declare const createBundle: <TIO extends IOLike<any, any>, TMetadata extends JsonObject = {}, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}, TEvents extends PluvRouterEventConfig<TIO, TPresence, TStorage> = {}>(client: PluvClient<TIO, TPresence, TStorage, TMetadata>, options?: CreateBundleOptions<TIO, TMetadata, TPresence, TStorage, TEvents>) => CreateBundle<TIO, TMetadata, TPresence, TStorage, TEvents>;
69
+ declare const createBundle: <TIO extends IOLike<any, any>, TMetadata extends JsonObject = {}, TPresence extends JsonObject = {}, TCrdt extends AbstractCrdtDocFactory<any> = NoopCrdtDocFactory, TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {}>(client: PluvClient<TIO, TPresence, TCrdt, TMetadata>, options?: CreateBundleOptions<TIO, TMetadata, TPresence, TCrdt, TEvents>) => CreateBundle<TIO, TMetadata, TPresence, TCrdt, TEvents>;
70
70
 
71
71
  export { type CreateBundle, type EventProxy, type PluvProviderProps, type PluvRoomProviderProps, type SubscriptionHookOptions, createBundle };
package/dist/index.d.ts CHANGED
@@ -1,25 +1,25 @@
1
- import { PluvRouterEventConfig, PluvClient, PluvRoomAddon, PluvRouter, MockedRoomEvents, MergeEvents, PluvRoomDebug, WebSocketConnection, UserInfo, AbstractRoom } from '@pluv/client';
2
- import { CrdtType, AbstractCrdtDoc, InferCrdtJson } from '@pluv/crdt';
3
- import { IOLike, JsonObject, MaybePromise, InferIOOutput, Id, IOEventMessage, InferIOInput } from '@pluv/types';
1
+ import { PluvRouterEventConfig, PluvClient, PluvRoomAddon, PluvRouter, MockedRoomEvents, MergeEvents, PluvRoomDebug, WebSocketConnection, UserInfo } from '@pluv/client';
2
+ import { AbstractCrdtDocFactory, NoopCrdtDocFactory, InferStorage, InferInitialStorageFn, InferCrdtJson } from '@pluv/crdt';
3
+ import { IOLike, JsonObject, MaybePromise, InferIOOutput, Id, IOEventMessage, InferIOInput, CrdtDocLike, RoomLike } from '@pluv/types';
4
4
  import { FC, ReactNode, Dispatch } from 'react';
5
5
 
6
6
  interface PluvProviderProps {
7
7
  children?: ReactNode;
8
8
  }
9
- type BaseRoomProviderProps<TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>> = {
9
+ type BaseRoomProviderProps<TPresence extends JsonObject, TCrdt extends AbstractCrdtDocFactory<any>> = {
10
10
  children?: ReactNode;
11
- initialStorage?: keyof TStorage extends never ? never : () => TStorage;
11
+ initialStorage?: keyof InferStorage<TCrdt> extends never ? never : InferInitialStorageFn<TCrdt>;
12
12
  room: string;
13
13
  } & (keyof TPresence extends never ? {
14
14
  initialPresence?: never;
15
15
  } : {
16
16
  initialPresence: TPresence;
17
17
  });
18
- type MockedRoomProviderProps<TIO extends IOLike, TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>, TEvents extends PluvRouterEventConfig<TIO, TPresence, TStorage> = {}> = BaseRoomProviderProps<TPresence, TStorage> & {
18
+ type MockedRoomProviderProps<TIO extends IOLike, TPresence extends JsonObject, TCrdt extends AbstractCrdtDocFactory<any>, TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {}> = BaseRoomProviderProps<TPresence, TCrdt> & {
19
19
  events?: MockedRoomEvents<MergeEvents<TEvents, TIO>>;
20
20
  };
21
21
  type MetadataGetter<TMetadata extends JsonObject> = TMetadata | (() => MaybePromise<TMetadata>);
22
- type PluvRoomProviderProps<TIO extends IOLike<any, any>, TMetadata extends JsonObject, TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>> = BaseRoomProviderProps<TPresence, TStorage> & {
22
+ type PluvRoomProviderProps<TIO extends IOLike<any, any>, TMetadata extends JsonObject, TPresence extends JsonObject, TCrdt extends AbstractCrdtDocFactory<any>> = BaseRoomProviderProps<TPresence, TCrdt> & {
23
23
  connect?: boolean;
24
24
  debug?: boolean | PluvRoomDebug<TIO>;
25
25
  onAuthorizationFail?: (error: Error) => void;
@@ -40,32 +40,32 @@ type EventProxy<TIO extends IOLike> = {
40
40
  useEvent: (callback: (data: Id<IOEventMessage<TIO, event>>) => void) => void;
41
41
  };
42
42
  };
43
- interface CreateBundle<TIO extends IOLike, TMetadata extends JsonObject, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}, TEvents extends PluvRouterEventConfig<TIO, TPresence, TStorage> = {}> {
44
- MockedRoomProvider: FC<MockedRoomProviderProps<TIO, TPresence, TStorage>>;
43
+ interface CreateBundle<TIO extends IOLike, TMetadata extends JsonObject, TPresence extends JsonObject = {}, TCrdt extends AbstractCrdtDocFactory<any> = NoopCrdtDocFactory, TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {}> {
44
+ MockedRoomProvider: FC<MockedRoomProviderProps<TIO, TPresence, TCrdt>>;
45
45
  PluvProvider: FC<PluvProviderProps>;
46
- PluvRoomProvider: FC<PluvRoomProviderProps<TIO, TMetadata, TPresence, TStorage>>;
46
+ PluvRoomProvider: FC<PluvRoomProviderProps<TIO, TMetadata, TPresence, TCrdt>>;
47
47
  event: EventProxy<MergeEvents<TEvents, TIO>>;
48
48
  useBroadcast: () => BroadcastProxy<MergeEvents<TEvents, TIO>>;
49
49
  useCanRedo: () => boolean;
50
50
  useCanUndo: () => boolean;
51
- useClient: () => PluvClient<TIO, TPresence, TStorage, TMetadata>;
51
+ useClient: () => PluvClient<TIO, TPresence, TCrdt, TMetadata>;
52
52
  useConnection: <T extends unknown = WebSocketConnection>(selector: (connection: WebSocketConnection) => T, options?: SubscriptionHookOptions<Id<T>>) => Id<T>;
53
- useDoc: () => AbstractCrdtDoc<TStorage>;
53
+ useDoc: () => CrdtDocLike<InferStorage<TCrdt>>;
54
54
  useEvent: <TType extends keyof InferIOOutput<MergeEvents<TEvents, TIO>>>(type: TType, callback: (data: Id<IOEventMessage<MergeEvents<TEvents, TIO>, TType>>) => void) => void;
55
55
  useMyPresence: <T extends unknown = TPresence>(selector?: (myPresence: TPresence) => T, options?: SubscriptionHookOptions<Id<T> | null>) => [myPresence: Id<T>, updateMyPresence: Dispatch<UpdateMyPresenceAction<TPresence>>];
56
56
  useMyself: <T extends unknown = UserInfo<TIO, TPresence>>(selector?: (myself: Id<UserInfo<TIO, TPresence>>) => T, options?: SubscriptionHookOptions<Id<T> | null>) => Id<T> | null;
57
57
  useOther: <T extends unknown = UserInfo<TIO, TPresence>>(connectionId: string, selector?: (other: UserInfo<TIO, TPresence>) => T, options?: SubscriptionHookOptions<T | null>) => T | null;
58
58
  useOthers: <T extends unknown = readonly UserInfo<TIO, TPresence>[]>(selector?: (other: readonly Id<UserInfo<TIO, TPresence>>[]) => T, options?: SubscriptionHookOptions<T>) => T;
59
59
  useRedo: () => () => void;
60
- useRoom: () => AbstractRoom<TIO, TPresence, TStorage>;
61
- useStorage: <TKey extends keyof TStorage, TData extends unknown = InferCrdtJson<TStorage[TKey]>>(key: TKey, selector?: (data: InferCrdtJson<TStorage[TKey]>) => TData, options?: SubscriptionHookOptions<TData | null>) => [data: TData | null, sharedType: TStorage[TKey] | null];
62
- useTransact: () => (fn: (storage: TStorage) => void, origin?: string) => void;
60
+ useRoom: () => RoomLike<TIO, TPresence, InferStorage<TCrdt>>;
61
+ useStorage: <TKey extends keyof InferStorage<TCrdt>, TData extends unknown = InferCrdtJson<InferStorage<TCrdt>[TKey]>>(key: TKey, selector?: (data: InferCrdtJson<InferStorage<TCrdt>[TKey]>) => TData, options?: SubscriptionHookOptions<TData | null>) => [data: TData | null, sharedType: InferStorage<TCrdt>[TKey] | null];
62
+ useTransact: () => (fn: (storage: InferStorage<TCrdt>) => void, origin?: string) => void;
63
63
  useUndo: () => () => void;
64
64
  }
65
- type CreateBundleOptions<TIO extends IOLike, TMetadata extends JsonObject = {}, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}, TEvents extends PluvRouterEventConfig<TIO, TPresence, TStorage> = {}> = {
66
- addons?: readonly PluvRoomAddon<TIO, TMetadata, TPresence, TStorage>[];
67
- router?: PluvRouter<TIO, TPresence, TStorage, TEvents>;
65
+ type CreateBundleOptions<TIO extends IOLike, TMetadata extends JsonObject = {}, TPresence extends JsonObject = {}, TCrdt extends AbstractCrdtDocFactory<any> = NoopCrdtDocFactory, TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {}> = {
66
+ addons?: readonly PluvRoomAddon<TIO, TMetadata, TPresence, TCrdt>[];
67
+ router?: PluvRouter<TIO, TPresence, InferStorage<TCrdt>, TEvents>;
68
68
  };
69
- declare const createBundle: <TIO extends IOLike<any, any>, TMetadata extends JsonObject = {}, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}, TEvents extends PluvRouterEventConfig<TIO, TPresence, TStorage> = {}>(client: PluvClient<TIO, TPresence, TStorage, TMetadata>, options?: CreateBundleOptions<TIO, TMetadata, TPresence, TStorage, TEvents>) => CreateBundle<TIO, TMetadata, TPresence, TStorage, TEvents>;
69
+ declare const createBundle: <TIO extends IOLike<any, any>, TMetadata extends JsonObject = {}, TPresence extends JsonObject = {}, TCrdt extends AbstractCrdtDocFactory<any> = NoopCrdtDocFactory, TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {}>(client: PluvClient<TIO, TPresence, TCrdt, TMetadata>, options?: CreateBundleOptions<TIO, TMetadata, TPresence, TCrdt, TEvents>) => CreateBundle<TIO, TMetadata, TPresence, TCrdt, TEvents>;
70
70
 
71
71
  export { type CreateBundle, type EventProxy, type PluvProviderProps, type PluvRoomProviderProps, type SubscriptionHookOptions, createBundle };
package/dist/index.js CHANGED
@@ -225,8 +225,12 @@ var useSyncExternalStoreWithSelector = (subscribe, getClientSnapshot, getServerS
225
225
  var import_jsx_runtime = require("react/jsx-runtime");
226
226
  var createBundle = (client, options = {}) => {
227
227
  const PluvContext = (0, import_react6.createContext)(null);
228
- const PluvRoomContext = (0, import_react6.createContext)(null);
229
- const MockedRoomContext = (0, import_react6.createContext)(null);
228
+ const PluvRoomContext = (0, import_react6.createContext)(
229
+ null
230
+ );
231
+ const MockedRoomContext = (0, import_react6.createContext)(
232
+ null
233
+ );
230
234
  const MockedRoomProvider = (0, import_react6.memo)((props) => {
231
235
  const { children, events, initialPresence, initialStorage, room: _room } = props;
232
236
  const [room] = (0, import_react6.useState)(() => {
package/dist/index.mjs CHANGED
@@ -192,8 +192,12 @@ var useSyncExternalStoreWithSelector = (subscribe, getClientSnapshot, getServerS
192
192
  import { jsx } from "react/jsx-runtime";
193
193
  var createBundle = (client, options = {}) => {
194
194
  const PluvContext = createContext(null);
195
- const PluvRoomContext = createContext(null);
196
- const MockedRoomContext = createContext(null);
195
+ const PluvRoomContext = createContext(
196
+ null
197
+ );
198
+ const MockedRoomContext = createContext(
199
+ null
200
+ );
197
201
  const MockedRoomProvider = memo((props) => {
198
202
  const { children, events, initialPresence, initialStorage, room: _room } = props;
199
203
  const [room] = useState4(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pluv/react",
3
- "version": "1.0.1",
3
+ "version": "2.0.0",
4
4
  "description": "@pluv/client React.js bindings",
5
5
  "author": "leedavidcs",
6
6
  "license": "MIT",
@@ -18,13 +18,13 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "fast-deep-equal": "^3.1.3",
21
- "@pluv/types": "^1.0.1",
22
- "@pluv/crdt": "^1.0.1"
21
+ "@pluv/crdt": "^2.0.0",
22
+ "@pluv/types": "^2.0.0"
23
23
  },
24
24
  "peerDependencies": {
25
25
  "@types/react": "^18.0.0 || ^19.0.0",
26
26
  "react": "^18.0.0 || ^19.0.0",
27
- "@pluv/client": "^1.0.1"
27
+ "@pluv/client": "^2.0.0"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/react": "^19.1.2",
@@ -32,9 +32,9 @@
32
32
  "react": "^19.1.0",
33
33
  "tsup": "^8.4.0",
34
34
  "typescript": "^5.8.3",
35
- "@pluv/client": "^1.0.1",
36
- "@pluv/tsconfig": "^1.0.1",
37
- "eslint-config-pluv": "^1.0.1"
35
+ "@pluv/client": "^2.0.0",
36
+ "@pluv/tsconfig": "^2.0.0",
37
+ "eslint-config-pluv": "^2.0.0"
38
38
  },
39
39
  "scripts": {
40
40
  "build": "tsup src/index.ts --format esm,cjs --dts --external react",
@@ -1,5 +1,4 @@
1
1
  import type {
2
- AbstractRoom,
3
2
  CreateRoomOptions,
4
3
  EnterRoomParams,
5
4
  MergeEvents,
@@ -13,8 +12,15 @@ import type {
13
12
  WebSocketConnection,
14
13
  } from "@pluv/client";
15
14
  import { MockedRoom, PluvRoom } from "@pluv/client";
16
- import type { AbstractCrdtDoc, CrdtType, InferCrdtJson } from "@pluv/crdt";
17
15
  import type {
16
+ AbstractCrdtDocFactory,
17
+ InferCrdtJson,
18
+ InferInitialStorageFn,
19
+ InferStorage,
20
+ NoopCrdtDocFactory,
21
+ } from "@pluv/crdt";
22
+ import type {
23
+ CrdtDocLike,
18
24
  Id,
19
25
  InferIOInput,
20
26
  InferIOOutput,
@@ -22,6 +28,7 @@ import type {
22
28
  IOLike,
23
29
  JsonObject,
24
30
  MaybePromise,
31
+ RoomLike,
25
32
  } from "@pluv/types";
26
33
  import fastDeepEqual from "fast-deep-equal";
27
34
  import type { Dispatch, FC, ReactNode } from "react";
@@ -41,19 +48,19 @@ export interface PluvProviderProps {
41
48
 
42
49
  type BaseRoomProviderProps<
43
50
  TPresence extends JsonObject,
44
- TStorage extends Record<string, CrdtType<any, any>>,
51
+ TCrdt extends AbstractCrdtDocFactory<any>,
45
52
  > = {
46
53
  children?: ReactNode;
47
- initialStorage?: keyof TStorage extends never ? never : () => TStorage;
54
+ initialStorage?: keyof InferStorage<TCrdt> extends never ? never : InferInitialStorageFn<TCrdt>;
48
55
  room: string;
49
56
  } & (keyof TPresence extends never ? { initialPresence?: never } : { initialPresence: TPresence });
50
57
 
51
58
  export type MockedRoomProviderProps<
52
59
  TIO extends IOLike,
53
60
  TPresence extends JsonObject,
54
- TStorage extends Record<string, CrdtType<any, any>>,
55
- TEvents extends PluvRouterEventConfig<TIO, TPresence, TStorage> = {},
56
- > = BaseRoomProviderProps<TPresence, TStorage> & {
61
+ TCrdt extends AbstractCrdtDocFactory<any>,
62
+ TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {},
63
+ > = BaseRoomProviderProps<TPresence, TCrdt> & {
57
64
  events?: MockedRoomEvents<MergeEvents<TEvents, TIO>>;
58
65
  };
59
66
 
@@ -65,8 +72,8 @@ export type PluvRoomProviderProps<
65
72
  TIO extends IOLike<any, any>,
66
73
  TMetadata extends JsonObject,
67
74
  TPresence extends JsonObject,
68
- TStorage extends Record<string, CrdtType<any, any>>,
69
- > = BaseRoomProviderProps<TPresence, TStorage> & {
75
+ TCrdt extends AbstractCrdtDocFactory<any>,
76
+ > = BaseRoomProviderProps<TPresence, TCrdt> & {
70
77
  connect?: boolean;
71
78
  debug?: boolean | PluvRoomDebug<TIO>;
72
79
  onAuthorizationFail?: (error: Error) => void;
@@ -99,13 +106,13 @@ export interface CreateBundle<
99
106
  TIO extends IOLike,
100
107
  TMetadata extends JsonObject,
101
108
  TPresence extends JsonObject = {},
102
- TStorage extends Record<string, CrdtType<any, any>> = {},
103
- TEvents extends PluvRouterEventConfig<TIO, TPresence, TStorage> = {},
109
+ TCrdt extends AbstractCrdtDocFactory<any> = NoopCrdtDocFactory,
110
+ TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {},
104
111
  > {
105
112
  // components
106
- MockedRoomProvider: FC<MockedRoomProviderProps<TIO, TPresence, TStorage>>;
113
+ MockedRoomProvider: FC<MockedRoomProviderProps<TIO, TPresence, TCrdt>>;
107
114
  PluvProvider: FC<PluvProviderProps>;
108
- PluvRoomProvider: FC<PluvRoomProviderProps<TIO, TMetadata, TPresence, TStorage>>;
115
+ PluvRoomProvider: FC<PluvRoomProviderProps<TIO, TMetadata, TPresence, TCrdt>>;
109
116
 
110
117
  // proxies
111
118
  event: EventProxy<MergeEvents<TEvents, TIO>>;
@@ -114,12 +121,12 @@ export interface CreateBundle<
114
121
  useBroadcast: () => BroadcastProxy<MergeEvents<TEvents, TIO>>;
115
122
  useCanRedo: () => boolean;
116
123
  useCanUndo: () => boolean;
117
- useClient: () => PluvClient<TIO, TPresence, TStorage, TMetadata>;
124
+ useClient: () => PluvClient<TIO, TPresence, TCrdt, TMetadata>;
118
125
  useConnection: <T extends unknown = WebSocketConnection>(
119
126
  selector: (connection: WebSocketConnection) => T,
120
127
  options?: SubscriptionHookOptions<Id<T>>,
121
128
  ) => Id<T>;
122
- useDoc: () => AbstractCrdtDoc<TStorage>;
129
+ useDoc: () => CrdtDocLike<InferStorage<TCrdt>>;
123
130
  useEvent: <TType extends keyof InferIOOutput<MergeEvents<TEvents, TIO>>>(
124
131
  type: TType,
125
132
  callback: (data: Id<IOEventMessage<MergeEvents<TEvents, TIO>, TType>>) => void,
@@ -142,16 +149,16 @@ export interface CreateBundle<
142
149
  options?: SubscriptionHookOptions<T>,
143
150
  ) => T;
144
151
  useRedo: () => () => void;
145
- useRoom: () => AbstractRoom<TIO, TPresence, TStorage>;
152
+ useRoom: () => RoomLike<TIO, TPresence, InferStorage<TCrdt>>;
146
153
  useStorage: <
147
- TKey extends keyof TStorage,
148
- TData extends unknown = InferCrdtJson<TStorage[TKey]>,
154
+ TKey extends keyof InferStorage<TCrdt>,
155
+ TData extends unknown = InferCrdtJson<InferStorage<TCrdt>[TKey]>,
149
156
  >(
150
157
  key: TKey,
151
- selector?: (data: InferCrdtJson<TStorage[TKey]>) => TData,
158
+ selector?: (data: InferCrdtJson<InferStorage<TCrdt>[TKey]>) => TData,
152
159
  options?: SubscriptionHookOptions<TData | null>,
153
- ) => [data: TData | null, sharedType: TStorage[TKey] | null];
154
- useTransact: () => (fn: (storage: TStorage) => void, origin?: string) => void;
160
+ ) => [data: TData | null, sharedType: InferStorage<TCrdt>[TKey] | null];
161
+ useTransact: () => (fn: (storage: InferStorage<TCrdt>) => void, origin?: string) => void;
155
162
  useUndo: () => () => void;
156
163
  }
157
164
 
@@ -159,30 +166,30 @@ export type CreateBundleOptions<
159
166
  TIO extends IOLike,
160
167
  TMetadata extends JsonObject = {},
161
168
  TPresence extends JsonObject = {},
162
- TStorage extends Record<string, CrdtType<any, any>> = {},
163
- TEvents extends PluvRouterEventConfig<TIO, TPresence, TStorage> = {},
169
+ TCrdt extends AbstractCrdtDocFactory<any> = NoopCrdtDocFactory,
170
+ TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {},
164
171
  > = {
165
- addons?: readonly PluvRoomAddon<TIO, TMetadata, TPresence, TStorage>[];
166
- router?: PluvRouter<TIO, TPresence, TStorage, TEvents>;
172
+ addons?: readonly PluvRoomAddon<TIO, TMetadata, TPresence, TCrdt>[];
173
+ router?: PluvRouter<TIO, TPresence, InferStorage<TCrdt>, TEvents>;
167
174
  };
168
175
 
169
176
  export const createBundle = <
170
177
  TIO extends IOLike<any, any>,
171
178
  TMetadata extends JsonObject = {},
172
179
  TPresence extends JsonObject = {},
173
- TStorage extends Record<string, CrdtType<any, any>> = {},
174
- TEvents extends PluvRouterEventConfig<TIO, TPresence, TStorage> = {},
180
+ TCrdt extends AbstractCrdtDocFactory<any> = NoopCrdtDocFactory,
181
+ TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {},
175
182
  >(
176
- client: PluvClient<TIO, TPresence, TStorage, TMetadata>,
177
- options: CreateBundleOptions<TIO, TMetadata, TPresence, TStorage, TEvents> = {},
178
- ): CreateBundle<TIO, TMetadata, TPresence, TStorage, TEvents> => {
183
+ client: PluvClient<TIO, TPresence, TCrdt, TMetadata>,
184
+ options: CreateBundleOptions<TIO, TMetadata, TPresence, TCrdt, TEvents> = {},
185
+ ): CreateBundle<TIO, TMetadata, TPresence, TCrdt, TEvents> => {
179
186
  /**
180
187
  * !HACK
181
188
  * @description We'll let the context error out if client is not provided,
182
189
  * and let the users deal with it.
183
190
  * @date October 27, 2022
184
191
  */
185
- const PluvContext = createContext<PluvClient<TIO, TPresence, TStorage, TMetadata>>(null as any);
192
+ const PluvContext = createContext<PluvClient<TIO, TPresence, TCrdt, TMetadata>>(null as any);
186
193
 
187
194
  /**
188
195
  * !HACK
@@ -190,20 +197,24 @@ export const createBundle = <
190
197
  * and let the users deal with it.
191
198
  * @date November 11, 2022
192
199
  */
193
- const PluvRoomContext = createContext<AbstractRoom<TIO, TPresence, TStorage>>(null as any);
200
+ const PluvRoomContext = createContext<RoomLike<TIO, TPresence, InferStorage<TCrdt>>>(
201
+ null as any,
202
+ );
194
203
 
195
- const MockedRoomContext = createContext<AbstractRoom<TIO, TPresence, TStorage> | null>(null);
204
+ const MockedRoomContext = createContext<RoomLike<TIO, TPresence, InferStorage<TCrdt>> | null>(
205
+ null,
206
+ );
196
207
 
197
- const MockedRoomProvider = memo<MockedRoomProviderProps<TIO, TPresence, TStorage>>((props) => {
208
+ const MockedRoomProvider = memo<MockedRoomProviderProps<TIO, TPresence, TCrdt>>((props) => {
198
209
  const { children, events, initialPresence, initialStorage, room: _room } = props;
199
210
 
200
- const [room] = useState<MockedRoom<TIO, TPresence, TStorage, TEvents>>(() => {
201
- return new MockedRoom<TIO, TPresence, TStorage, TEvents>(_room, {
211
+ const [room] = useState<MockedRoom<TIO, TPresence, TCrdt, TEvents>>(() => {
212
+ return new MockedRoom<TIO, TPresence, TCrdt, TEvents>(_room, {
202
213
  events,
203
214
  initialPresence,
204
215
  initialStorage:
205
216
  typeof initialStorage === "function"
206
- ? client._defs.initialStorage?.getFactory(initialStorage)
217
+ ? (client._defs.initialStorage?.getFactory(initialStorage) as TCrdt)
207
218
  : client._defs.initialStorage,
208
219
  });
209
220
  });
@@ -217,7 +228,7 @@ export const createBundle = <
217
228
 
218
229
  MockedRoomProvider.displayName = "MockedRoomProvider";
219
230
 
220
- const PluvRoomProvider = memo<PluvRoomProviderProps<TIO, TMetadata, TPresence, TStorage>>(
231
+ const PluvRoomProvider = memo<PluvRoomProviderProps<TIO, TMetadata, TPresence, TCrdt>>(
221
232
  (props) => {
222
233
  const {
223
234
  children,
@@ -242,7 +253,7 @@ export const createBundle = <
242
253
  return !!room.metadata ? room.metadata.parse(resolved) : resolved;
243
254
  });
244
255
 
245
- const [room] = useState<PluvRoom<TIO, TMetadata, TPresence, TStorage, TEvents>>(() => {
256
+ const [room] = useState<PluvRoom<TIO, TMetadata, TPresence, TCrdt, TEvents>>(() => {
246
257
  return client.createRoom(_room, {
247
258
  addons: options.addons,
248
259
  debug,
@@ -254,7 +265,7 @@ export const createBundle = <
254
265
  metadata,
255
266
  onAuthorizationFail,
256
267
  router: options.router,
257
- } as CreateRoomOptions<TIO, TPresence, TStorage, TMetadata, TEvents>);
268
+ } as CreateRoomOptions<TIO, TPresence, TCrdt, TMetadata, TEvents>);
258
269
  });
259
270
 
260
271
  useEffect(() => {
@@ -320,8 +331,7 @@ export const createBundle = <
320
331
 
321
332
  PluvProvider.displayName = "PluvProvider";
322
333
 
323
- const useClient = (): PluvClient<TIO, TPresence, TStorage, TMetadata> =>
324
- useContext(PluvContext);
334
+ const useClient = (): PluvClient<TIO, TPresence, TCrdt, TMetadata> => useContext(PluvContext);
325
335
 
326
336
  const useRoom = () => {
327
337
  const room = useContext(PluvRoomContext);
@@ -619,13 +629,13 @@ export const createBundle = <
619
629
  };
620
630
 
621
631
  const useStorage = <
622
- TKey extends keyof TStorage,
623
- TData extends unknown = InferCrdtJson<TStorage[TKey]>,
632
+ TKey extends keyof InferStorage<TCrdt>,
633
+ TData extends unknown = InferCrdtJson<InferStorage<TCrdt>[TKey]>,
624
634
  >(
625
635
  key: TKey,
626
- selector = identity as (data: InferCrdtJson<TStorage[TKey]>) => TData,
636
+ selector = identity as (data: InferCrdtJson<InferStorage<TCrdt>[TKey]>) => TData,
627
637
  options?: SubscriptionHookOptions<TData | null>,
628
- ): [data: TData | null, sharedType: TStorage[TKey] | null] => {
638
+ ): [data: TData | null, sharedType: InferStorage<TCrdt>[TKey] | null] => {
629
639
  const room = useRoom();
630
640
  const rerender = useRerender();
631
641
 
@@ -638,12 +648,12 @@ export const createBundle = <
638
648
  [key, room],
639
649
  );
640
650
 
641
- const getSnapshot = useCallback((): InferCrdtJson<TStorage[TKey]> | null => {
651
+ const getSnapshot = useCallback((): InferCrdtJson<InferStorage<TCrdt>[TKey]> | null => {
642
652
  return room.getStorageJson(key);
643
653
  }, [key, room]);
644
654
 
645
655
  const _selector = useCallback(
646
- (snapshot: InferCrdtJson<TStorage[TKey]> | null) => {
656
+ (snapshot: InferCrdtJson<InferStorage<TCrdt>[TKey]> | null) => {
647
657
  return snapshot === null ? null : selector(snapshot);
648
658
  },
649
659
  [selector],