@pluv/client 0.15.0 → 0.16.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.
@@ -1,18 +1,18 @@
1
1
 
2
- > @pluv/client@0.15.0 build /home/runner/work/pluv/pluv/packages/client
2
+ > @pluv/client@0.16.1 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
6
6
  CLI Using tsconfig: tsconfig.json
7
- CLI tsup v8.0.1
7
+ CLI tsup v8.0.2
8
8
  CLI Target: es6
9
9
  ESM Build start
10
10
  CJS Build start
11
- CJS dist/index.js 44.17 KB
12
- CJS ⚡️ Build success in 80ms
13
- ESM dist/index.mjs 42.92 KB
14
- ESM ⚡️ Build success in 82ms
11
+ ESM dist/index.mjs 41.52 KB
12
+ ESM ⚡️ Build success in 144ms
13
+ CJS dist/index.js 42.79 KB
14
+ CJS ⚡️ Build success in 156ms
15
15
  DTS Build start
16
- DTS ⚡️ Build success in 2982ms
17
- DTS dist/index.d.mts 14.31 KB
18
- DTS dist/index.d.ts 14.31 KB
16
+ DTS ⚡️ Build success in 3486ms
17
+ DTS dist/index.d.mts 13.94 KB
18
+ DTS dist/index.d.ts 13.94 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,163 @@
1
1
  # @pluv/client
2
2
 
3
+ ## 0.16.1
4
+
5
+ ### Patch Changes
6
+
7
+ - @pluv/crdt@0.16.1
8
+ - @pluv/types@0.16.1
9
+
10
+ ## 0.16.0
11
+
12
+ ### Minor Changes
13
+
14
+ - 4280220: ## Breaking Changes
15
+
16
+ - Storage types are now kept on the root of the document.
17
+ - Previously, `@pluv/crdt-yjs` kept all shared-types on a hidden Yjs Map called `storage` on the root of the Yjs Doc. Now all shared-types are kept on the root of the Yjs Doc instead. This behavior should be more in-line with how shared-types are documented to be used from Yjs.
18
+ - `@pluv/client` and `@pluv/react` no-longer re-export `@pluv/crdt-yjs`. This package will now need to be installed separately.
19
+
20
+ ```bash
21
+ # if installing @pluv/client
22
+ npm install @pluv/client @pluv/crdt-yjs
23
+ # if installing @pluv/react
24
+ npm install @pluv/react @pluv/crdt-yjs
25
+ ```
26
+
27
+ ```ts
28
+ // Before:
29
+ import { createClient, y } from "@pluv/client";
30
+ // After:
31
+ import { createClient } from "@pluv/client";
32
+ import { yjs } from "@pluv/crdt-yjs"; // y renamed to yjs
33
+ ```
34
+
35
+ - The `y` import has been renamed to `yjs`.
36
+ ```ts
37
+ // Before:
38
+ import { y } from "@pluv/crdt-yjs";
39
+ // After:
40
+ import { yjs } from "@pluv/crdt-yjs";
41
+ ```
42
+ - `@pluv/crdt-yjs` functions no-longer return Yjs shared-types directly, but instead return an `AbstractCrdtType` from `@pluv/crdt` (new package). This also affects methods that return storage shared types in both `@pluv/client` and `@pluv/react` from functions like `PluvRoom.getStorage` and `PluvRoom.useStorage`.
43
+
44
+ ```ts
45
+ // Before:
46
+ import { y } from "@pluv/crdt-yjs";
47
+ import type { Array as YArray, Map as YMap } from "yjs";
48
+
49
+ const array: YArray<YMap<{ message: string }>> = y.array([
50
+ y.object({ message: "Hello" }),
51
+ ]);
52
+
53
+ array.push([y.object({ message: "World!" })]);
54
+
55
+ // After:
56
+ import type { CrdtYjsArray, CrdtYjsObject } from "@pluv/crdt-yjs";
57
+ import { yjs } from "@pluv/crdt-yjs";
58
+ import type { Array as YArray } from "yjs";
59
+
60
+ const array: CrdtYjsArray<CrdtYjsObject<{ message: string }>> = yjs.array([
61
+ yjs.object({ message: "Hello" }),
62
+ ]);
63
+
64
+ array.push(yjs.object({ message: "World!" }));
65
+
66
+ // use .value to get the underlying yjs type
67
+ const yarray: YArray<YMap<{ message: string }>> = array.value;
68
+ ```
69
+
70
+ - `initialStorage` must now use the `doc` function from `@pluv/crdt-yjs` to be defined. This also affects `@pluv/react`.
71
+
72
+ ```ts
73
+ // Before:
74
+ import { createClient, y } from "@pluv/client";
75
+
76
+ const client = createClient({
77
+ /* ... */
78
+ });
79
+
80
+ client.createRoom({
81
+ // ...
82
+ initialStorage: () => ({
83
+ messages: y.array([y.object({ message: "Hello world!" })]),
84
+ }),
85
+ });
86
+
87
+ // After:
88
+ import { createClient } from "@pluv/client";
89
+ // This is now imported separately
90
+ import { yjs } from "@pluv/crdt-yjs";
91
+
92
+ const client = createClient({
93
+ /* ... */
94
+ });
95
+
96
+ client.createRoom({
97
+ // ...
98
+ initialStorage: yjs.doc(() => ({
99
+ messages: yjs.array([yjs.object({ message: "Hello world!" })]),
100
+ })),
101
+ });
102
+ ```
103
+
104
+ - `@pluv/client` can now instead use [loro](https://github.com/loro-dev/loro) instead of [yjs](https://github.com/yjs/yjs).
105
+ ```bash
106
+ npm install @pluv/client @pluv/crdt-loro loro-crdt
107
+ ```
108
+ - If you are using storage features with pluv, `@pluv/io` must now specify which crdt library (i.e. `@pluv/crdt-yjs` or `@pluv/crdt-loro`) it is meant to use.
109
+
110
+ ```ts
111
+ import { loro } from "@pluv/crdt-loro";
112
+ import { yjs } from "@pluv/crdt-yjs";
113
+ import { createIO } from "@pluv/io";
114
+
115
+ const io = createIO({
116
+ // ...
117
+ // If using loro
118
+ crdt: loro,
119
+ // If using yjs
120
+ crdt: yjs,
121
+ });
122
+ ```
123
+
124
+ - `PluvRoom.getDoc()` from `@pluv/client` no-longer returns the Yjs Doc instance, but rather a `AbstractCrdtDoc` instance from `@pluv/crdt`. This also affects the hook from `@pluv/react`.
125
+
126
+ ```ts
127
+ // Before:
128
+ import { Doc as YDoc } from "yjs";
129
+
130
+ const room: PluvRoom = client.createRoom({
131
+ /* ... */
132
+ });
133
+
134
+ const doc: YDoc = room.getDoc();
135
+
136
+ // After:
137
+ import { CrdtYjsDoc } from "@pluv/crdt-yjs";
138
+ import { Doc as YDoc } from "yjs";
139
+
140
+ const room: PluvRoom = client.createRoom({
141
+ /* ... */
142
+ });
143
+
144
+ const doc: CrdtYjsDoc<any> = room.getDoc();
145
+ const ydoc: YDoc = doc.value;
146
+ ```
147
+
148
+ - `@pluv/client` and `@pluv/react` now may return `null` when retrieving storage while storage is being initialized.
149
+
150
+ ```ts
151
+ const sharedType = room.getStorage("messages"); // This may be null
152
+
153
+ const [data, sharedType] = useStorage("messages"); // data and sharedType may both be null
154
+ ```
155
+
156
+ ### Patch Changes
157
+
158
+ - @pluv/crdt@0.16.0
159
+ - @pluv/types@0.16.0
160
+
3
161
  ## 0.15.0
4
162
 
5
163
  ### Patch Changes
@@ -218,7 +376,7 @@
218
376
 
219
377
  ## @pluv/react
220
378
 
221
- `@pluv/react`'s `createRoomBundle` now exposes 5 new react hooks: `usePluvCanRedo`, `usePluvCanUndo`, `usePluvRedo`, `usePluvUndo` and `usePluvTransact`.
379
+ `@pluv/react`'s `createRoomBundle` now exposes 5 new react hooks: `useCanRedo`, `useCanUndo`, `useRedo`, `useUndo` and `useTransact`.
222
380
 
223
381
  Refer to the code-example below to better understand how to undo and redo with your `createRoomBundle`.
224
382
 
@@ -230,47 +388,41 @@
230
388
 
231
389
  const { createRoomBundle } = createBundle(client);
232
390
 
233
- const {
234
- usePluvCanRedo,
235
- usePluvCanUndo,
236
- usePluvRedo,
237
- usePluvStorage,
238
- usePluvTransact,
239
- usePluvUndo,
240
- } = createRoomBundle({
241
- initialStorage: () => ({
242
- messages: y.array<string>([]),
243
- }),
244
- /**
245
- * @description This is the same `captureTimeout` option from yjs's UndoManager.
246
- * This specifies a number in ms, during which edits are merged together to be
247
- * undone together. Set this to 0, to track each transacted change individually.
248
- * @see (@link https://docs.yjs.dev/api/undo-manager)
249
- * @default 500
250
- */
251
- captureTimeout: 500,
252
- /**
253
- * @desription This is the same `trackedOrigins` option from yjs's UndoManager.
254
- * This specifies transaction origins (strings only) to filter which transactions
255
- * can be undone.
256
- * When omitted, the user's connection id will be tracked. When provided,
257
- * specifies additional tracked origins besides the user's connection id.
258
- * @see (@link https://docs.yjs.dev/api/undo-manager)
259
- * @default undefined
260
- */
261
- trackedOrigins: ["user-123"],
262
- });
391
+ const { useCanRedo, useCanUndo, useRedo, useStorage, useTransact, useUndo } =
392
+ createRoomBundle({
393
+ initialStorage: () => ({
394
+ messages: y.array<string>([]),
395
+ }),
396
+ /**
397
+ * @description This is the same `captureTimeout` option from yjs's UndoManager.
398
+ * This specifies a number in ms, during which edits are merged together to be
399
+ * undone together. Set this to 0, to track each transacted change individually.
400
+ * @see (@link https://docs.yjs.dev/api/undo-manager)
401
+ * @default 500
402
+ */
403
+ captureTimeout: 500,
404
+ /**
405
+ * @desription This is the same `trackedOrigins` option from yjs's UndoManager.
406
+ * This specifies transaction origins (strings only) to filter which transactions
407
+ * can be undone.
408
+ * When omitted, the user's connection id will be tracked. When provided,
409
+ * specifies additional tracked origins besides the user's connection id.
410
+ * @see (@link https://docs.yjs.dev/api/undo-manager)
411
+ * @default undefined
412
+ */
413
+ trackedOrigins: ["user-123"],
414
+ });
263
415
 
264
416
  /**
265
417
  * @description Check whether calling undo will mutate storage
266
418
  */
267
- const canUndo: boolean = usePluvCanUndo();
419
+ const canUndo: boolean = useCanUndo();
268
420
  /**
269
421
  * @description Check whether calling redo will mutate storage
270
422
  */
271
- const canRedo: boolean = usePluvCanRedo();
423
+ const canRedo: boolean = useCanRedo();
272
424
 
273
- const [messages, sharedType] = usePluvStorage("messages");
425
+ const [messages, sharedType] = useStorage("messages");
274
426
 
275
427
  /**
276
428
  * @description Calling transact will enable a storage mutation to be undone/redone.
@@ -279,7 +431,7 @@
279
431
  *
280
432
  * You can specify a 2nd parameter to transact with a different transaction origin.
281
433
  */
282
- const transact = usePluvTransact();
434
+ const transact = useTransact();
283
435
 
284
436
  transact(() => {
285
437
  sharedType.push(["hello world!"]);
@@ -293,14 +445,14 @@
293
445
  /**
294
446
  * @description Undoes the last valid mutation to storage
295
447
  */
296
- const undo = usePluvUndo();
448
+ const undo = useUndo();
297
449
 
298
450
  undo();
299
451
 
300
452
  /**
301
453
  * @description Re-applies the last undone mutation to storage
302
454
  */
303
- const redo = usePluvRedo();
455
+ const redo = useRedo();
304
456
 
305
457
  redo();
306
458
  ```
package/README.md CHANGED
@@ -5,12 +5,12 @@
5
5
  <br />
6
6
  <img src="https://github.com/pluv-io/pluv/blob/master/assets/pluv-icon-192x192.png?raw=true" alt="Pluv.IO" width="180" style="border-radius:16px" />
7
7
  <br />
8
- Pluv.IO (preview)
8
+ <a href="https://pluv.io/docs/introduction">Pluv.IO (preview)</a>
9
9
  <br />
10
10
  </h1>
11
11
 
12
12
  <h3 align="center">Multi-platform, E2E type-safe realtime packages</h3>
13
- <h4 align="center">💕 Inspired by <a href="https://trpc.io">trpc</a> 💕 Built with <a href="https://docs.yjs.dev/">yjs</a> 💕</h4>
13
+ <h4 align="center">💕 Inspired by <a href="https://trpc.io">trpc</a> 💕 <a href="https://docs.yjs.dev/">yjs</a> 💕 and <a href="https://developers.cloudflare.com/">Cloudflare</a> 💕 </h4>
14
14
 
15
15
  <p align="center">
16
16
  <a href="https://www.npmjs.com/package/@pluv/client">
@@ -19,14 +19,10 @@
19
19
  <a href="https://github.com/pluv-io/pluv/blob/master/LICENSE">
20
20
  <img alt="GitHub" src="https://img.shields.io/github/license/pluv-io/pluv" alt="License MIT" />
21
21
  </a>
22
- <img src="https://badgen.net/badge/-/TypeScript?icon=typescript&label&labelColor=blue&color=555555" alt="TypeScript" />
23
22
  <a href="https://commitizen.github.io/cz-cli/">
24
23
  <img src="https://img.shields.io/badge/commitizen-friendly-brightgreen.svg" alt="Commitizen friendly" />
25
24
  </a>
26
- </p>
27
-
28
- <p align="center">
29
- <img src="https://github.com/pluv-io/pluv/blob/master/assets/demo-events.gif?raw=true" alt="Demo" />
25
+ <img src="https://badgen.net/badge/-/TypeScript?icon=typescript&label&labelColor=blue&color=555555" alt="TypeScript" />
30
26
  </p>
31
27
 
32
28
  ## `@pluv/client`
@@ -39,13 +35,13 @@
39
35
 
40
36
  ```bash
41
37
  # npm
42
- npm install @pluv/client yjs
38
+ npm install @pluv/client @pluv/crdt-yjs yjs
43
39
 
44
40
  # yarn
45
- yarn add @pluv/client yjs
41
+ yarn add @pluv/client @pluv/crdt-yjs yjs
46
42
 
47
43
  # pnpm
48
- pnpm add @pluv/client yjs
44
+ pnpm add @pluv/client @pluv/crdt-yjs yjs
49
45
  ```
50
46
 
51
47
  If you plan on using presence and/or storage, make sure to also install `zod`.
@@ -53,7 +49,8 @@ If you plan on using presence and/or storage, make sure to also install `zod`.
53
49
  ## Basic Example
54
50
 
55
51
  ```ts
56
- import { createClient, y } from "@pluv/client";
52
+ import { createClient } from "@pluv/client";
53
+ import { yjs } from "@pluv/crdt-yjs";
57
54
  import { z } from "zod";
58
55
  // Import the PluvIO instance as a type from your server file
59
56
  import { type io } from "./server";
@@ -79,7 +76,7 @@ interface Storage {
79
76
  // Create a room to join
80
77
  const room = client.createRoom<Presence, Storage>("my-room", {
81
78
  initialPresence: { cursor: null },
82
- initialStorage: () => ({ messages: y.array([]) }),
79
+ initialStorage: yjs.doc(() => ({ messages: yjs.array([]) })),
83
80
  onAuthorizationFail: (error) => {
84
81
  console.log(error.message);
85
82
  },
package/dist/index.d.mts CHANGED
@@ -1,10 +1,8 @@
1
- import { InferYjsSharedTypeJson, TrackOriginOptions, array, map, object, text, xmlElement, xmlFragment, xmlText } from '@pluv/crdt-yjs';
2
- export { InferYjsSharedTypeJson, TrackOriginOptions } from '@pluv/crdt-yjs';
1
+ import { AbstractCrdtType, AbstractCrdtDoc, InferCrdtStorageJson, AbstractCrdtDocFactory } from '@pluv/crdt';
2
+ export { AbstractCrdtType, InferCrdtStorageJson } from '@pluv/crdt';
3
3
  import * as _pluv_types from '@pluv/types';
4
4
  import { IOLike, InferIOOutput, Id, IOEventMessage, JsonObject, InferIOAuthorizeUser, InferIOAuthorize, InferIOInput, InputZodLike, InferIOAuthorizeRequired } from '@pluv/types';
5
5
  export { BaseUser, EventMessage, EventRecord, IOEventMessage } from '@pluv/types';
6
- import { AbstractType, Doc } from 'yjs';
7
- export { AbstractType } from 'yjs';
8
6
  import { Subject } from 'wonka';
9
7
 
10
8
  type EventNotifierSubscriptionCallback<TIO extends IOLike, TEvent extends keyof InferIOOutput<TIO>> = (value: Id<IOEventMessage<TIO, TEvent>>) => void;
@@ -43,29 +41,31 @@ interface StateNotifierSubjects<TIO extends IOLike, TPresence extends JsonObject
43
41
  "my-presence": Subject<TPresence | null>;
44
42
  myself: Subject<Readonly<Id<UserInfo<TIO>>> | null>;
45
43
  others: Subject<readonly Id<UserInfo<TIO>>[]>;
44
+ "storage-loaded": Subject<boolean>;
46
45
  }
47
46
  type InferSubjectValue<TIO extends IOLike, TPresence extends JsonObject, TSubject extends keyof StateNotifierSubjects<TIO, TPresence>> = StateNotifierSubjects<TIO, TPresence>[TSubject] extends Subject<infer IValue> ? Id<IValue> : never;
48
47
  type SubscriptionCallback<TIO extends IOLike, TPresence extends JsonObject, TSubject extends keyof StateNotifierSubjects<TIO, TPresence>> = (value: InferSubjectValue<TIO, TPresence, TSubject>) => void;
49
48
 
50
- declare abstract class AbstractRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}> {
49
+ declare abstract class AbstractRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}> {
51
50
  readonly id: string;
52
51
  constructor(room: string);
52
+ abstract storageLoaded: boolean;
53
53
  abstract broadcast<TEvent extends keyof InferIOInput<TIO>>(event: TEvent, data: Id<InferIOInput<TIO>[TEvent]>): void;
54
54
  abstract canRedo(): boolean;
55
55
  abstract canUndo(): boolean;
56
- abstract getDoc(): Doc;
56
+ abstract getDoc(): AbstractCrdtDoc<TStorage>;
57
57
  abstract event<TEvent extends keyof InferIOOutput<TIO>>(event: TEvent, callback: EventNotifierSubscriptionCallback<TIO, TEvent>): () => void;
58
58
  abstract getConnection(): WebSocketConnection;
59
59
  abstract getMyPresence(): TPresence;
60
60
  abstract getMyself(): Id<UserInfo<TIO, TPresence>> | null;
61
61
  abstract getOther(connectionId: string): Id<UserInfo<TIO, TPresence>> | null;
62
62
  abstract getOthers(): readonly Id<UserInfo<TIO, TPresence>>[];
63
- abstract getStorage<TKey extends keyof TStorage>(key: TKey): TStorage[TKey];
63
+ abstract getStorage<TKey extends keyof TStorage>(key: TKey): TStorage[TKey] | null;
64
64
  abstract other(connectionId: string, callback: OtherNotifierSubscriptionCallback<TIO>): () => void;
65
65
  abstract redo(): void;
66
- abstract storage<TKey extends keyof TStorage>(key: TKey, fn: (value: InferYjsSharedTypeJson<TStorage[TKey]>) => void): () => void;
66
+ abstract storage<TKey extends keyof TStorage>(key: TKey, fn: (value: InferCrdtStorageJson<TStorage[TKey]>) => void): () => void;
67
67
  abstract storageRoot(fn: (value: {
68
- [P in keyof TStorage]: InferYjsSharedTypeJson<TStorage[P]>;
68
+ [P in keyof TStorage]: InferCrdtStorageJson<TStorage[P]>;
69
69
  }) => void): () => void;
70
70
  abstract subscribe<TSubject extends keyof StateNotifierSubjects<TIO, TPresence>>(name: TSubject, callback: SubscriptionCallback<TIO, TPresence, TSubject>): () => void;
71
71
  abstract transact(fn: (storage: TStorage) => void, origin?: string): void;
@@ -84,16 +84,56 @@ declare abstract class AbstractStorageStore {
84
84
  abstract initialize(): Promise<void>;
85
85
  }
86
86
 
87
- type CrdtManagerOptions<TStorage extends Record<string, AbstractType<any>> = {}> = {
87
+ type CrdtManagerOptions<TStorage extends Record<string, AbstractCrdtType<any, any>> = {}> = {
88
88
  encodedState?: string | Uint8Array | null;
89
- initialStorage?: () => TStorage;
90
- } & TrackOriginOptions;
89
+ initialStorage?: AbstractCrdtDocFactory<TStorage>;
90
+ };
91
91
 
92
92
  type UsersManagerConfig<TPresence extends JsonObject = {}> = {
93
93
  initialPresence?: TPresence;
94
94
  presence?: InputZodLike<TPresence>;
95
95
  };
96
96
 
97
+ type MockedRoomEvents<TIO extends IOLike> = Partial<{
98
+ [P in keyof InferIOInput<TIO>]: (data: Id<InferIOInput<TIO>[P]>) => Partial<InferIOOutput<TIO>>;
99
+ }>;
100
+ type MockedRoomConfig<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}> = {
101
+ events?: MockedRoomEvents<TIO>;
102
+ } & Omit<CrdtManagerOptions<TStorage>, "encodedState"> & UsersManagerConfig<TPresence>;
103
+ declare class MockedRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}> extends AbstractRoom<TIO, TPresence, TStorage> {
104
+ private _crdtManager;
105
+ private _crdtNotifier;
106
+ private _eventNotifier;
107
+ private _events?;
108
+ private _otherNotifier;
109
+ private _state;
110
+ private _stateNotifier;
111
+ private _subscriptions;
112
+ private _usersManager;
113
+ constructor(room: string, options: MockedRoomConfig<TIO, TPresence, TStorage>);
114
+ get storageLoaded(): boolean;
115
+ broadcast<TEvent extends keyof InferIOInput<TIO>>(event: TEvent, data: Id<InferIOInput<TIO>[TEvent]>): void;
116
+ canRedo: () => boolean;
117
+ canUndo: () => boolean;
118
+ event: <TEvent extends keyof InferIOOutput<TIO>>(event: TEvent, callback: EventNotifierSubscriptionCallback<TIO, TEvent>) => (() => void);
119
+ getConnection(): WebSocketConnection;
120
+ getDoc(): AbstractCrdtDoc<TStorage>;
121
+ getMyPresence: () => TPresence;
122
+ getMyself: () => Id<UserInfo<TIO, TPresence>> | null;
123
+ getOther: (connectionId: string) => Id<UserInfo<TIO, TPresence>> | null;
124
+ getOthers: () => readonly Id<UserInfo<TIO, TPresence>>[];
125
+ getStorage: <TKey extends keyof TStorage>(key: TKey) => TStorage[TKey] | null;
126
+ other: (connectionId: string, callback: OtherNotifierSubscriptionCallback<TIO>) => (() => void);
127
+ redo: () => void;
128
+ storage: <TKey extends keyof TStorage>(key: TKey, fn: (value: InferCrdtStorageJson<TStorage[TKey]>) => void) => (() => void);
129
+ storageRoot: (fn: (value: { [P in keyof TStorage]: InferCrdtStorageJson<TStorage[P]>; }) => void) => (() => void);
130
+ subscribe: <TSubject extends keyof StateNotifierSubjects<TIO, TPresence>>(name: TSubject, callback: SubscriptionCallback<TIO, TPresence, TSubject>) => (() => void);
131
+ transact: (fn: (storage: TStorage) => void, origin?: string) => void;
132
+ undo: () => void;
133
+ updateMyPresence: (presence: Partial<TPresence>) => void;
134
+ private _observeCrdt;
135
+ }
136
+
97
137
  declare global {
98
138
  var process: {
99
139
  env: {
@@ -114,8 +154,8 @@ type RoomEndpoints<TIO extends IOLike> = {
114
154
  } : {
115
155
  authEndpoint?: undefined;
116
156
  });
117
- type PluvRoomAddon<TIO extends IOLike = IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}> = (input: PluvRoomAddonInput<TIO, TPresence, TStorage>) => Partial<PluvRoomAddonResult>;
118
- interface PluvRoomAddonInput<TIO extends IOLike = IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}> {
157
+ type PluvRoomAddon<TIO extends IOLike = IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}> = (input: PluvRoomAddonInput<TIO, TPresence, TStorage>) => Partial<PluvRoomAddonResult>;
158
+ interface PluvRoomAddonInput<TIO extends IOLike = IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}> {
119
159
  room: PluvRoom<TIO, TPresence, TStorage>;
120
160
  }
121
161
  interface PluvRoomAddonResult {
@@ -125,15 +165,14 @@ type PluvRoomDebug<TIO extends IOLike> = Id<{
125
165
  output: readonly (keyof InferIOOutput<TIO>)[];
126
166
  input: readonly (keyof InferIOInput<TIO>)[];
127
167
  }>;
128
- type PluvRoomOptions<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}> = {
168
+ type PluvRoomOptions<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}> = {
129
169
  addons?: readonly PluvRoomAddon<TIO, TPresence, TStorage>[];
130
170
  debug?: boolean | PluvRoomDebug<TIO>;
131
171
  onAuthorizationFail?: (error: Error) => void;
132
172
  } & Omit<CrdtManagerOptions<TStorage>, "encodedState"> & UsersManagerConfig<TPresence>;
133
- type RoomConfig<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}> = RoomEndpoints<TIO> & PluvRoomOptions<TIO, TPresence, TStorage> & TrackOriginOptions;
134
- declare class PluvRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}> extends AbstractRoom<TIO, TPresence, TStorage> {
173
+ type RoomConfig<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}> = RoomEndpoints<TIO> & PluvRoomOptions<TIO, TPresence, TStorage>;
174
+ declare class PluvRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}> extends AbstractRoom<TIO, TPresence, TStorage> {
135
175
  readonly _endpoints: RoomEndpoints<TIO>;
136
- private _captureTimeout;
137
176
  private _crdtManager;
138
177
  private _crdtNotifier;
139
178
  private _debug;
@@ -146,11 +185,11 @@ declare class PluvRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TS
146
185
  private _storageStore;
147
186
  private _subscriptions;
148
187
  private _timeouts;
149
- private _trackedOrigins;
150
188
  private _windowListeners;
151
189
  private _wsListeners;
152
190
  private _usersManager;
153
191
  constructor(room: string, options: RoomConfig<TIO, TPresence, TStorage>);
192
+ get storageLoaded(): boolean;
154
193
  get webSocket(): WebSocket | null;
155
194
  broadcast<TEvent extends keyof InferIOInput<TIO>>(event: TEvent, data: Id<InferIOInput<TIO>[TEvent]>): void;
156
195
  canRedo: () => boolean;
@@ -159,16 +198,16 @@ declare class PluvRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TS
159
198
  disconnect(): Promise<void>;
160
199
  event: <TEvent extends keyof InferIOOutput<TIO>>(event: TEvent, callback: EventNotifierSubscriptionCallback<TIO, TEvent>) => (() => void);
161
200
  getConnection(): WebSocketConnection;
162
- getDoc(): Doc;
201
+ getDoc(): AbstractCrdtDoc<TStorage>;
163
202
  getMyPresence: () => TPresence;
164
203
  getMyself: () => Id<UserInfo<TIO, TPresence>> | null;
165
204
  getOther: (connectionId: string) => Id<UserInfo<TIO, TPresence>> | null;
166
205
  getOthers: () => readonly Id<UserInfo<TIO, TPresence>>[];
167
- getStorage: <TKey extends keyof TStorage>(key: TKey) => TStorage[TKey];
206
+ getStorage: <TKey extends keyof TStorage>(key: TKey) => TStorage[TKey] | null;
168
207
  other: (connectionId: string, callback: OtherNotifierSubscriptionCallback<TIO>) => (() => void);
169
208
  redo: () => void;
170
- storage: <TKey extends keyof TStorage>(key: TKey, fn: (value: InferYjsSharedTypeJson<TStorage[TKey]>) => void) => (() => void);
171
- storageRoot: (fn: (value: { [P in keyof TStorage]: InferYjsSharedTypeJson<TStorage[P]>; }) => void) => (() => void);
209
+ storage: <TKey extends keyof TStorage>(key: TKey, fn: (value: InferCrdtStorageJson<TStorage[TKey]>) => void) => (() => void);
210
+ storageRoot: (fn: (value: { [P in keyof TStorage]: InferCrdtStorageJson<TStorage[P]>; }) => void) => (() => void);
172
211
  subscribe: <TSubject extends keyof StateNotifierSubjects<TIO, TPresence>>(name: TSubject, callback: SubscriptionCallback<TIO, TPresence, TSubject>) => (() => void);
173
212
  transact: (fn: (storage: TStorage) => void, origin?: string) => void;
174
213
  undo: () => void;
@@ -187,7 +226,6 @@ declare class PluvRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TS
187
226
  private _getAddon;
188
227
  private _getAuthFetchOptions;
189
228
  private _getAuthorization;
190
- private _getTrackedOrigins;
191
229
  private _getWsEndpoint;
192
230
  private _handleExit;
193
231
  private _handlePresenceUpdatedMessage;
@@ -234,9 +272,9 @@ declare class PluvClient<TIO extends IOLike = IOLike> {
234
272
  private _wsEndpoint;
235
273
  private _rooms;
236
274
  constructor(options: PluvClientOptions<TIO>);
237
- createRoom: <TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}>(room: string, options?: PluvRoomOptions<TIO, TPresence, TStorage>) => PluvRoom<TIO, TPresence, TStorage>;
275
+ createRoom: <TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}>(room: string, options: PluvRoomOptions<TIO, TPresence, TStorage>) => PluvRoom<TIO, TPresence, TStorage>;
238
276
  enter: (room: string | PluvRoom<TIO, any, any>) => Promise<PluvRoom<TIO, JsonObject, any>>;
239
- getRoom: <TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}>(room: string) => PluvRoom<TIO, TPresence, TStorage> | null;
277
+ getRoom: <TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}>(room: string) => PluvRoom<TIO, TPresence, TStorage> | null;
240
278
  getRooms: () => readonly PluvRoom<TIO, JsonObject, any>[];
241
279
  leave: (room: string | PluvRoom<TIO, any, any>) => Promise<void>;
242
280
  private _logDebug;
@@ -244,54 +282,4 @@ declare class PluvClient<TIO extends IOLike = IOLike> {
244
282
 
245
283
  declare const createClient: <TIO extends IOLike<_pluv_types.IOAuthorize<any, any>, {}, {}, {}, {}> = IOLike<_pluv_types.IOAuthorize<any, any>, {}, {}, {}, {}>>(options: PluvClientOptions<TIO>) => PluvClient<TIO>;
246
284
 
247
- type MockedRoomEvents<TIO extends IOLike> = Partial<{
248
- [P in keyof InferIOInput<TIO>]: (data: Id<InferIOInput<TIO>[P]>) => Partial<InferIOOutput<TIO>>;
249
- }>;
250
- type MockedRoomConfig<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}> = {
251
- events?: MockedRoomEvents<TIO>;
252
- } & Omit<CrdtManagerOptions<TStorage>, "encodedState"> & UsersManagerConfig<TPresence>;
253
- declare class MockedRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}> extends AbstractRoom<TIO, TPresence, TStorage> {
254
- private _crdtManager;
255
- private _crdtNotifier;
256
- private _eventNotifier;
257
- private _events?;
258
- private _otherNotifier;
259
- private _state;
260
- private _stateNotifier;
261
- private _subscriptions;
262
- private _usersManager;
263
- constructor(room: string, options: MockedRoomConfig<TIO, TPresence, TStorage>);
264
- broadcast<TEvent extends keyof InferIOInput<TIO>>(event: TEvent, data: Id<InferIOInput<TIO>[TEvent]>): void;
265
- canRedo: () => boolean;
266
- canUndo: () => boolean;
267
- event: <TEvent extends keyof InferIOOutput<TIO>>(event: TEvent, callback: EventNotifierSubscriptionCallback<TIO, TEvent>) => (() => void);
268
- getConnection(): WebSocketConnection;
269
- getDoc(): Doc;
270
- getMyPresence: () => TPresence;
271
- getMyself: () => Id<UserInfo<TIO, TPresence>> | null;
272
- getOther: (connectionId: string) => Id<UserInfo<TIO, TPresence>> | null;
273
- getOthers: () => readonly Id<UserInfo<TIO, TPresence>>[];
274
- getStorage: <TKey extends keyof TStorage>(key: TKey) => TStorage[TKey];
275
- other: (connectionId: string, callback: OtherNotifierSubscriptionCallback<TIO>) => (() => void);
276
- redo: () => void;
277
- storage: <TKey extends keyof TStorage>(key: TKey, fn: (value: InferYjsSharedTypeJson<TStorage[TKey]>) => void) => (() => void);
278
- storageRoot: (fn: (value: { [P in keyof TStorage]: InferYjsSharedTypeJson<TStorage[P]>; }) => void) => (() => void);
279
- subscribe: <TSubject extends keyof StateNotifierSubjects<TIO, TPresence>>(name: TSubject, callback: SubscriptionCallback<TIO, TPresence, TSubject>) => (() => void);
280
- transact: (fn: (storage: TStorage) => void, origin?: string) => void;
281
- undo: () => void;
282
- updateMyPresence: (presence: Partial<TPresence>) => void;
283
- private _observeCrdt;
284
- }
285
-
286
- declare const y_array: typeof array;
287
- declare const y_map: typeof map;
288
- declare const y_object: typeof object;
289
- declare const y_text: typeof text;
290
- declare const y_xmlElement: typeof xmlElement;
291
- declare const y_xmlFragment: typeof xmlFragment;
292
- declare const y_xmlText: typeof xmlText;
293
- declare namespace y {
294
- export { y_array as array, y_map as map, y_object as object, y_text as text, y_xmlElement as xmlElement, y_xmlFragment as xmlFragment, y_xmlText as xmlText };
295
- }
296
-
297
- export { AbstractRoom, AbstractStorageStore, ConnectionState, MockedRoom, type MockedRoomConfig, type MockedRoomEvents, PluvClient, type PluvClientOptions, PluvRoom, type PluvRoomAddon, type PluvRoomAddonInput, type PluvRoomAddonResult, type PluvRoomDebug, type UserInfo, type WebSocketConnection, type WebSocketState, createClient, y };
285
+ export { AbstractRoom, AbstractStorageStore, ConnectionState, MockedRoom, type MockedRoomConfig, type MockedRoomEvents, PluvClient, type PluvClientOptions, PluvRoom, type PluvRoomAddon, type PluvRoomAddonInput, type PluvRoomAddonResult, type PluvRoomDebug, type UserInfo, type WebSocketConnection, type WebSocketState, createClient };