@pluv/client 2.2.0 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +6 -6
- package/CHANGELOG.md +1004 -996
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,48 +1,62 @@
|
|
|
1
1
|
# @pluv/client
|
|
2
2
|
|
|
3
|
+
## 2.2.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- @pluv/crdt@2.2.2
|
|
8
|
+
- @pluv/types@2.2.2
|
|
9
|
+
|
|
10
|
+
## 2.2.1
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- @pluv/crdt@2.2.1
|
|
15
|
+
- @pluv/types@2.2.1
|
|
16
|
+
|
|
3
17
|
## 2.2.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
|
6
20
|
|
|
7
21
|
- 3ce1547: Updated typings for `PluvRoom.getDoc` to be narrower to get the native doc type.
|
|
8
22
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
23
|
+
```ts
|
|
24
|
+
import { createClient } from "@pluv/client";
|
|
25
|
+
import { yjs } from "@pluv/crdt-yjs";
|
|
26
|
+
import type { Doc as YDoc } from "yjs";
|
|
13
27
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
28
|
+
const client = createClient({
|
|
29
|
+
// ...
|
|
30
|
+
crdt: yjs,
|
|
31
|
+
});
|
|
32
|
+
const room = client.createRoom("example-room");
|
|
19
33
|
|
|
20
|
-
|
|
34
|
+
const doc = room.getDoc();
|
|
21
35
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
36
|
+
// This is now typed as the native YDoc
|
|
37
|
+
doc.value;
|
|
38
|
+
// ^? const value: YDoc
|
|
39
|
+
```
|
|
26
40
|
|
|
27
41
|
- fd3bfe2: Added the ability to listen to the room's underlying websocket's event listeners.
|
|
28
42
|
- aee40cb: Updated `presence` types to be more lenient (i.e. no-longer extends `JsonObject`). This is to enable types like `.passthrough` with zod, which can be useful for integrating `yjs.awareness` with libraries such as [lexical](https://lexical.dev/).
|
|
29
43
|
- edd1789: **DEPRECATED** `PluvRoom.storageLoaded` will be removed in v3. Added `PluvRoom.getStorageLoaded` with improved detection of when the storage was synced.
|
|
30
44
|
|
|
31
|
-
|
|
32
|
-
|
|
45
|
+
```ts
|
|
46
|
+
const room = client.createRoom("example-room");
|
|
33
47
|
|
|
34
|
-
|
|
35
|
-
|
|
48
|
+
// Before
|
|
49
|
+
room.storageLoaded;
|
|
36
50
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
51
|
+
// After
|
|
52
|
+
room.getStorageLoaded();
|
|
53
|
+
```
|
|
40
54
|
|
|
41
55
|
### Patch Changes
|
|
42
56
|
|
|
43
57
|
- 48191fa: Fixed `PluvRoom.getDoc` not returning a stable doc reference for a single connection.
|
|
44
|
-
|
|
45
|
-
|
|
58
|
+
- @pluv/crdt@2.2.0
|
|
59
|
+
- @pluv/types@2.2.0
|
|
46
60
|
|
|
47
61
|
## 2.1.0
|
|
48
62
|
|
|
@@ -50,96 +64,96 @@
|
|
|
50
64
|
|
|
51
65
|
- e8d8fbc: **DEPRECATED** Subscribing to data via string parameters on `PluvRoom.subscribe` is deprecated, to be removed in v3. To subscribe to things such as `myself`, `my-presence` and `others`, you must now do so via nested properties on the `subscribe` object (see example below).
|
|
52
66
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
```ts
|
|
68
|
+
const room = client.createRoom("example-room");
|
|
69
|
+
|
|
70
|
+
// Before (now deprecated)
|
|
71
|
+
room.subscribe("connection", (state) => {});
|
|
72
|
+
room.subscribe("my-presence", (myPresence) => {});
|
|
73
|
+
room.subscribe("myself", (myself) => {});
|
|
74
|
+
room.subscribe("others", (others) => {});
|
|
75
|
+
room.subscribe("storage-loaded", (storageLoaded) => {});
|
|
76
|
+
|
|
77
|
+
// After
|
|
78
|
+
room.subscribe.connection((state) => {});
|
|
79
|
+
room.subscribe.myPresence((myPresence) => {});
|
|
80
|
+
room.subscribe.myself((myself) => {});
|
|
81
|
+
room.subscribe.others((others) => {});
|
|
82
|
+
room.subscribe.storageLoaded((storageLoaded) => {});
|
|
83
|
+
```
|
|
70
84
|
|
|
71
85
|
- d5ac29e: **DEPRECATED** `PluvRoom.event`, `PluvRoom.storage`, `PluvRoom.storageRoot` and `PluvRoom.other` have all been deprecated, to be removed in v3. These now exist under `PluvRoom.subscribe` instead.
|
|
72
86
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
```ts
|
|
88
|
+
const room = client.createRoom("example-room");
|
|
89
|
+
|
|
90
|
+
// Before (now deprecated)
|
|
91
|
+
room.event.receiveMessage((event) => {});
|
|
92
|
+
room.storage.messages((messages) => {});
|
|
93
|
+
room.storageRoot((storage) => {});
|
|
94
|
+
room.other(("id_...", other) => {});
|
|
95
|
+
|
|
96
|
+
// After
|
|
97
|
+
room.subscribe.event.receiveMessage((event) => {});
|
|
98
|
+
room.subscribe.storage.messages((messages) => {});
|
|
99
|
+
room.subscribe.storageRoot((storage) => {});
|
|
100
|
+
room.subscribe.other(("id_...", other) => {});
|
|
101
|
+
```
|
|
88
102
|
|
|
89
103
|
- 5ca5cb6: Updated `PluvRoom.storage` to also allow subscribing to storage fields as nested properties.
|
|
90
104
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
105
|
+
```ts
|
|
106
|
+
const client = createClient({
|
|
107
|
+
// ...
|
|
108
|
+
initialStorage: yjs.doc((t) => ({
|
|
109
|
+
messages: yjs.array<string>(),
|
|
110
|
+
})),
|
|
111
|
+
});
|
|
98
112
|
|
|
99
|
-
|
|
113
|
+
const room = client.createRoom("example-room");
|
|
100
114
|
|
|
101
|
-
|
|
102
|
-
|
|
115
|
+
// The two statements below are equivalent.
|
|
116
|
+
room.storage("messages", (value) => {});
|
|
103
117
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
118
|
+
// You can now subscribe to storage fields as nested properties like so
|
|
119
|
+
room.storage.messages((value) => {});
|
|
120
|
+
```
|
|
107
121
|
|
|
108
122
|
- 4acbe1e: Updated `PluvRoom.storage` to also allow subscribing to the root storage when no field is provided.
|
|
109
123
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
124
|
+
```ts
|
|
125
|
+
const client = createClient({
|
|
126
|
+
// ...
|
|
127
|
+
initialStorage: yjs.doc((t) => ({
|
|
128
|
+
messages: yjs.array<string>(),
|
|
129
|
+
})),
|
|
130
|
+
});
|
|
117
131
|
|
|
118
|
-
|
|
132
|
+
const room = client.createRoom("example-room");
|
|
119
133
|
|
|
120
|
-
|
|
121
|
-
|
|
134
|
+
room.storage("messages", (value) => {});
|
|
135
|
+
// ^? const value: string[];
|
|
122
136
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
137
|
+
// You can now subscribe to the storage root when no key is provided
|
|
138
|
+
room.storage((value) => {});
|
|
139
|
+
// ^? const value: { messages: string[] };
|
|
140
|
+
```
|
|
127
141
|
|
|
128
142
|
- e8d8fbc: Updated `PluvRoom.subscribe` so that `PluvRoom.event` and `PluvRoom.storage` can be accessed as properties under `PluvRoom.subscribe`.
|
|
129
143
|
|
|
130
|
-
|
|
131
|
-
|
|
144
|
+
```ts
|
|
145
|
+
const room = client.createRoom("example-room");
|
|
132
146
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
147
|
+
// These are now available under the subscribe object
|
|
148
|
+
room.subscribe.event.receiveEvent((event) => {});
|
|
149
|
+
room.subscribe.storage.messages((data) => {});
|
|
150
|
+
```
|
|
137
151
|
|
|
138
152
|
### Patch Changes
|
|
139
153
|
|
|
140
154
|
- a86ff5e: Updated internal types to simplify the type for `PluvRoom.broadcast` and `PluvRoom.event`.
|
|
141
|
-
|
|
142
|
-
|
|
155
|
+
- @pluv/crdt@2.1.0
|
|
156
|
+
- @pluv/types@2.1.0
|
|
143
157
|
|
|
144
158
|
## 2.0.2
|
|
145
159
|
|
|
@@ -153,8 +167,8 @@
|
|
|
153
167
|
### Patch Changes
|
|
154
168
|
|
|
155
169
|
- 1b93b18: Fixed `ConnectionState` not being exported.
|
|
156
|
-
|
|
157
|
-
|
|
170
|
+
- @pluv/crdt@2.0.1
|
|
171
|
+
- @pluv/types@2.0.1
|
|
158
172
|
|
|
159
173
|
## 2.0.0
|
|
160
174
|
|
|
@@ -164,24 +178,24 @@
|
|
|
164
178
|
- 0806212: Fix the room's id not being defined during the initialization of addons.
|
|
165
179
|
- 3a34dbb: Fixed `initialStorage` on `PluvClient.createRoom` not overwriting the `initialStorage` from the `PluvClient` constructor.
|
|
166
180
|
- Updated dependencies [047a1d8]
|
|
167
|
-
|
|
168
|
-
|
|
181
|
+
- @pluv/types@2.0.0
|
|
182
|
+
- @pluv/crdt@2.0.0
|
|
169
183
|
|
|
170
184
|
## 1.0.2
|
|
171
185
|
|
|
172
186
|
### Patch Changes
|
|
173
187
|
|
|
174
188
|
- d87159c: Restored `@pluv/addon-indexeddb` functionality, and fixed `@pluv/addon-indexeddb` sometimes duplicating storage operations based on `initialStorage` values.
|
|
175
|
-
|
|
176
|
-
|
|
189
|
+
- @pluv/crdt@1.0.2
|
|
190
|
+
- @pluv/types@1.0.2
|
|
177
191
|
|
|
178
192
|
## 1.0.1
|
|
179
193
|
|
|
180
194
|
### Patch Changes
|
|
181
195
|
|
|
182
196
|
- c583be9: Fixed storage race condition that occurred when 2 users joined a room near simultaneously that would cause users to have mismatched storage states from the server (and thereby preventing updates from properly registering) until the user reconnected.
|
|
183
|
-
|
|
184
|
-
|
|
197
|
+
- @pluv/crdt@1.0.1
|
|
198
|
+
- @pluv/types@1.0.1
|
|
185
199
|
|
|
186
200
|
## 1.0.0
|
|
187
201
|
|
|
@@ -189,31 +203,31 @@
|
|
|
189
203
|
|
|
190
204
|
- af94706: pluv.io is now stable and production ready!
|
|
191
205
|
|
|
192
|
-
|
|
206
|
+
With this v1 release, pluv.io will now follow [semantic versioning](https://semver.org/) with more comprehensive release notes for future changes to the library.
|
|
193
207
|
|
|
194
|
-
|
|
208
|
+
Checkout the [full documentation here](https://pluv.io/docs/introduction) to get started today!
|
|
195
209
|
|
|
196
210
|
### Patch Changes
|
|
197
211
|
|
|
198
212
|
- Updated dependencies [af94706]
|
|
199
|
-
|
|
200
|
-
|
|
213
|
+
- @pluv/crdt@1.0.0
|
|
214
|
+
- @pluv/types@1.0.0
|
|
201
215
|
|
|
202
216
|
## 0.44.2
|
|
203
217
|
|
|
204
218
|
### Patch Changes
|
|
205
219
|
|
|
206
220
|
- 6cfd36f: Update `PluvRoom` to attempt to reconnect if currently disconnected when the window is re-focused.
|
|
207
|
-
|
|
208
|
-
|
|
221
|
+
- @pluv/crdt@0.44.2
|
|
222
|
+
- @pluv/types@0.44.2
|
|
209
223
|
|
|
210
224
|
## 0.44.1
|
|
211
225
|
|
|
212
226
|
### Patch Changes
|
|
213
227
|
|
|
214
228
|
- 67c081d: Fix `PluvRoom._reconnect` not being called with the last used metadata (from `PluvRoom.connect`).
|
|
215
|
-
|
|
216
|
-
|
|
229
|
+
- @pluv/crdt@0.44.1
|
|
230
|
+
- @pluv/types@0.44.1
|
|
217
231
|
|
|
218
232
|
## 0.44.0
|
|
219
233
|
|
|
@@ -225,8 +239,8 @@
|
|
|
225
239
|
|
|
226
240
|
- fba9354: Fix potential edge case where event handlers may be called redundantly.
|
|
227
241
|
- bc2d684: Fix `PluvRoom` not properly reconnecting when connections are unavailable.
|
|
228
|
-
|
|
229
|
-
|
|
242
|
+
- @pluv/crdt@0.44.0
|
|
243
|
+
- @pluv/types@0.44.0
|
|
230
244
|
|
|
231
245
|
## 0.43.0
|
|
232
246
|
|
|
@@ -234,25 +248,25 @@
|
|
|
234
248
|
|
|
235
249
|
- 65d9172: Added configurable limits for client-side validation. These should only be updated if you control the server and the server limits have been changed.
|
|
236
250
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
251
|
+
```ts
|
|
252
|
+
// defaults
|
|
253
|
+
createClient({
|
|
254
|
+
limits: {
|
|
255
|
+
presenceMaxSize: 512,
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
```
|
|
245
259
|
|
|
246
|
-
|
|
247
|
-
|
|
260
|
+
- @pluv/crdt@0.43.0
|
|
261
|
+
- @pluv/types@0.43.0
|
|
248
262
|
|
|
249
263
|
## 0.42.0
|
|
250
264
|
|
|
251
265
|
### Patch Changes
|
|
252
266
|
|
|
253
267
|
- 7ae56bf: Periodically sync connection ids with the server to clear stale connections.
|
|
254
|
-
|
|
255
|
-
|
|
268
|
+
- @pluv/crdt@0.42.0
|
|
269
|
+
- @pluv/types@0.42.0
|
|
256
270
|
|
|
257
271
|
## 0.41.7
|
|
258
272
|
|
|
@@ -266,16 +280,16 @@
|
|
|
266
280
|
### Patch Changes
|
|
267
281
|
|
|
268
282
|
- 71642fa: Fix error about missing wsEndpoint.
|
|
269
|
-
|
|
270
|
-
|
|
283
|
+
- @pluv/crdt@0.41.6
|
|
284
|
+
- @pluv/types@0.41.6
|
|
271
285
|
|
|
272
286
|
## 0.41.5
|
|
273
287
|
|
|
274
288
|
### Patch Changes
|
|
275
289
|
|
|
276
290
|
- b3b7b30: Fix error being thrown about missing wsEndpoint when a public key is provided.
|
|
277
|
-
|
|
278
|
-
|
|
291
|
+
- @pluv/crdt@0.41.5
|
|
292
|
+
- @pluv/types@0.41.5
|
|
279
293
|
|
|
280
294
|
## 0.41.4
|
|
281
295
|
|
|
@@ -289,16 +303,16 @@
|
|
|
289
303
|
### Patch Changes
|
|
290
304
|
|
|
291
305
|
- 49051c0: Fix presence keys becoming lost, causing presence objects to be partial and failing schema validation.
|
|
292
|
-
|
|
293
|
-
|
|
306
|
+
- @pluv/crdt@0.41.3
|
|
307
|
+
- @pluv/types@0.41.3
|
|
294
308
|
|
|
295
309
|
## 0.41.2
|
|
296
310
|
|
|
297
311
|
### Patch Changes
|
|
298
312
|
|
|
299
313
|
- 37956d3: When presence is received for a user that is not currently being tracked, `PluvRoom` now automatically updates `others` to include the connection of the received presence.
|
|
300
|
-
|
|
301
|
-
|
|
314
|
+
- @pluv/crdt@0.41.2
|
|
315
|
+
- @pluv/types@0.41.2
|
|
302
316
|
|
|
303
317
|
## 0.41.1
|
|
304
318
|
|
|
@@ -314,22 +328,22 @@
|
|
|
314
328
|
- 41aa439: **BREAKING** User's presence is now limited to be at most 512 bytes. If the presence is any larger, the `PluvRoom` will now throw an error.
|
|
315
329
|
- 555b88d: Users can now have multiple simultaneous connections. Previously, if a user tried to open a connection to a room while already being connected to the room, the new connection would be blocked. Now, when the user opens another connection, the new connection will be opened and initialized with their latest presence.
|
|
316
330
|
|
|
317
|
-
|
|
331
|
+
Users can only have 1 identity and 1 presence, which means that all presence updates will sync across all of that user's connections. This means that even when a user opens multiple connections, they will only appear once in `others`.
|
|
318
332
|
|
|
319
333
|
### Patch Changes
|
|
320
334
|
|
|
321
335
|
- eb2d903: `PluvRoom` attempts to reconnect immediately after receiving a `close` event, instead of waiting for the reconnect timer. After failing the initial reconnect will the reconnects poll on the timer.
|
|
322
336
|
- 555b88d: Fixed the `presence` type of `other` and `others` to equal the inferred presence type.
|
|
323
|
-
|
|
324
|
-
|
|
337
|
+
- @pluv/crdt@0.41.0
|
|
338
|
+
- @pluv/types@0.41.0
|
|
325
339
|
|
|
326
340
|
## 0.40.2
|
|
327
341
|
|
|
328
342
|
### Patch Changes
|
|
329
343
|
|
|
330
344
|
- 6fbc2fe: Update `PluvClient.createRoom` so that the 2nd parameter is optional.
|
|
331
|
-
|
|
332
|
-
|
|
345
|
+
- @pluv/crdt@0.40.2
|
|
346
|
+
- @pluv/types@0.40.2
|
|
333
347
|
|
|
334
348
|
## 0.40.1
|
|
335
349
|
|
|
@@ -358,75 +372,75 @@
|
|
|
358
372
|
|
|
359
373
|
- e6ddddc: **BREAKING** Moved the `metadata` parameter from the constructor of `PluvRoom` to `PluvClient.connect`. The `metadata` parameter from the constructor of `PluvRoom` is now the validation schema for `metadata` passed through from `PluvClient`.
|
|
360
374
|
|
|
361
|
-
|
|
375
|
+
This should not be breaking for most users, as the recommended way to enter a room has always been via `PluvClient.enter(room)` (i.e. these are mostly internal-only changes).
|
|
362
376
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
377
|
+
```ts
|
|
378
|
+
// Before
|
|
379
|
+
const room = new Room("my-room", { metadata: { hello: "world" } });
|
|
366
380
|
|
|
367
|
-
|
|
381
|
+
await room.connect();
|
|
368
382
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
383
|
+
// After
|
|
384
|
+
const room = new Room("my-room", {
|
|
385
|
+
metadata: z.object({ hello: z.string() }),
|
|
386
|
+
});
|
|
373
387
|
|
|
374
|
-
|
|
375
|
-
|
|
388
|
+
await room.connect({ metadata: { hello: "world" } });
|
|
389
|
+
```
|
|
376
390
|
|
|
377
391
|
- e6ddddc: **BREAKING** Moved the `metadata` parameter from `PluvClient.createRoom` to `PluvClient.enter`.
|
|
378
392
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
393
|
+
```ts
|
|
394
|
+
// Before
|
|
395
|
+
const room = client.createRoom({
|
|
396
|
+
// ...
|
|
397
|
+
metadata: { hello: "world" },
|
|
398
|
+
// ...
|
|
399
|
+
});
|
|
386
400
|
|
|
387
|
-
|
|
401
|
+
client.enter(room);
|
|
388
402
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
403
|
+
// After
|
|
404
|
+
const room = client.createRoom({
|
|
405
|
+
// ...
|
|
406
|
+
});
|
|
393
407
|
|
|
394
|
-
|
|
395
|
-
|
|
408
|
+
client.enter(room, { metadata });
|
|
409
|
+
```
|
|
396
410
|
|
|
397
411
|
### Patch Changes
|
|
398
412
|
|
|
399
413
|
- e6ddddc: Improved handling of polling-reconnects to `PluvRoom` after the websocket closes (depending on the close event's code).
|
|
400
414
|
- 2cfb68d: Add the ability to configure the reconnect timeout (in milliseconds) for a `PluvRoom`, and lowered the default reconnect timeout from 30s to 5s. Values will be automatically clamped to between 1s and 60s.
|
|
401
415
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
416
|
+
```ts
|
|
417
|
+
// Both of these are valid
|
|
418
|
+
const room = client.createRoom("my-room", {
|
|
419
|
+
// Set timeout to a fixed 10s
|
|
420
|
+
reconnectTimeoutMs: 10_000,
|
|
421
|
+
});
|
|
408
422
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
423
|
+
const room = client.createRoom("my-room", {
|
|
424
|
+
/**
|
|
425
|
+
* `attempts` is the count of failed reconnect attempts, starting from 0 on the first attempt.
|
|
426
|
+
* The returned value will be how long until the next attempt.
|
|
427
|
+
*/
|
|
428
|
+
reconnectTimeoutMs: ({ attempts }) => {
|
|
429
|
+
return 10_000 + 1_000 * Math.pow(2, attempts);
|
|
430
|
+
},
|
|
431
|
+
});
|
|
432
|
+
```
|
|
419
433
|
|
|
420
|
-
|
|
421
|
-
|
|
434
|
+
- @pluv/crdt@0.39.0
|
|
435
|
+
- @pluv/types@0.39.0
|
|
422
436
|
|
|
423
437
|
## 0.38.14
|
|
424
438
|
|
|
425
439
|
### Patch Changes
|
|
426
440
|
|
|
427
441
|
- 886a1f9: Fix cases where the user's own presence was getting updated excessively, and without re-triggering subscriptions.
|
|
428
|
-
|
|
429
|
-
|
|
442
|
+
- @pluv/crdt@0.38.14
|
|
443
|
+
- @pluv/types@0.38.14
|
|
430
444
|
|
|
431
445
|
## 0.38.13
|
|
432
446
|
|
|
@@ -440,24 +454,24 @@
|
|
|
440
454
|
### Patch Changes
|
|
441
455
|
|
|
442
456
|
- b617726: Fix broken type narrowing for `PluvRoom.event` and `PluvRoom.broadcast`.
|
|
443
|
-
|
|
444
|
-
|
|
457
|
+
- @pluv/crdt@0.38.12
|
|
458
|
+
- @pluv/types@0.38.12
|
|
445
459
|
|
|
446
460
|
## 0.38.11
|
|
447
461
|
|
|
448
462
|
### Patch Changes
|
|
449
463
|
|
|
450
464
|
- 5ac1aba: Fix the default `wsEndpoint` parameter (for when `@pluv/platform-pluv` is being used).
|
|
451
|
-
|
|
452
|
-
|
|
465
|
+
- @pluv/crdt@0.38.11
|
|
466
|
+
- @pluv/types@0.38.11
|
|
453
467
|
|
|
454
468
|
## 0.38.10
|
|
455
469
|
|
|
456
470
|
### Patch Changes
|
|
457
471
|
|
|
458
472
|
- cadd963: Update the user's presence locally only via `PluvRoom.updateMyPresence` (i.e. do not update the user's own presence from WebSocket messages) to avoid update delays. This should fix some cases of "jitter" depending on network latecy.
|
|
459
|
-
|
|
460
|
-
|
|
473
|
+
- @pluv/crdt@0.38.10
|
|
474
|
+
- @pluv/types@0.38.10
|
|
461
475
|
|
|
462
476
|
## 0.38.9
|
|
463
477
|
|
|
@@ -506,16 +520,16 @@
|
|
|
506
520
|
### Patch Changes
|
|
507
521
|
|
|
508
522
|
- 8346273: Disallow the `# @pluv/client character in router event names.
|
|
509
|
-
|
|
510
|
-
|
|
523
|
+
- @pluv/crdt@0.38.3
|
|
524
|
+
- @pluv/types@0.38.3
|
|
511
525
|
|
|
512
526
|
## 0.38.2
|
|
513
527
|
|
|
514
528
|
### Patch Changes
|
|
515
529
|
|
|
516
530
|
- de35f0b: Require `PluvRouter` event names to be formatted as valid JavaScript variable names.
|
|
517
|
-
|
|
518
|
-
|
|
531
|
+
- @pluv/crdt@0.38.2
|
|
532
|
+
- @pluv/types@0.38.2
|
|
519
533
|
|
|
520
534
|
## 0.38.1
|
|
521
535
|
|
|
@@ -533,8 +547,8 @@
|
|
|
533
547
|
### Patch Changes
|
|
534
548
|
|
|
535
549
|
- Updated dependencies [f4ceca3]
|
|
536
|
-
|
|
537
|
-
|
|
550
|
+
- @pluv/types@0.38.0
|
|
551
|
+
- @pluv/crdt@0.38.0
|
|
538
552
|
|
|
539
553
|
## 0.37.7
|
|
540
554
|
|
|
@@ -562,24 +576,24 @@
|
|
|
562
576
|
### Patch Changes
|
|
563
577
|
|
|
564
578
|
- a9c3d17: Fix `publicKey` not being properly set on `PluvClient` when `publicKey` is a function.
|
|
565
|
-
|
|
566
|
-
|
|
579
|
+
- @pluv/crdt@0.37.4
|
|
580
|
+
- @pluv/types@0.37.4
|
|
567
581
|
|
|
568
582
|
## 0.37.3
|
|
569
583
|
|
|
570
584
|
### Patch Changes
|
|
571
585
|
|
|
572
586
|
- 9ae837b: Add missing schema validation for room metadata.
|
|
573
|
-
|
|
574
|
-
|
|
587
|
+
- @pluv/crdt@0.37.3
|
|
588
|
+
- @pluv/types@0.37.3
|
|
575
589
|
|
|
576
590
|
## 0.37.2
|
|
577
591
|
|
|
578
592
|
### Patch Changes
|
|
579
593
|
|
|
580
594
|
- 11920af: Updated the default `wsEndpoint` for `PluvClient` when `publicKey` is provided to be correct.
|
|
581
|
-
|
|
582
|
-
|
|
595
|
+
- @pluv/crdt@0.37.2
|
|
596
|
+
- @pluv/types@0.37.2
|
|
583
597
|
|
|
584
598
|
## 0.37.1
|
|
585
599
|
|
|
@@ -587,24 +601,24 @@
|
|
|
587
601
|
|
|
588
602
|
- e923a8d: Added support for specifying the `publicKey` param for `createClient` as a function with metadata. This is particularly useful for non-static Next.js applications built with Cloudflare Pages.
|
|
589
603
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
604
|
+
```ts
|
|
605
|
+
import { createClient } from "@pluv/client";
|
|
606
|
+
import { z } from "zod";
|
|
593
607
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
608
|
+
export const client = createClient({
|
|
609
|
+
// Can be a string
|
|
610
|
+
publicKey: "pk_abc123...",
|
|
597
611
|
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
612
|
+
// Or can be a function
|
|
613
|
+
metadata: z.object({
|
|
614
|
+
publicKey: z.string().min(1, "Required"),
|
|
615
|
+
}),
|
|
616
|
+
publicKey: ({ metadata }) => metadata.publicKey,
|
|
617
|
+
});
|
|
618
|
+
```
|
|
605
619
|
|
|
606
|
-
|
|
607
|
-
|
|
620
|
+
- @pluv/crdt@0.37.1
|
|
621
|
+
- @pluv/types@0.37.1
|
|
608
622
|
|
|
609
623
|
## 0.37.0
|
|
610
624
|
|
|
@@ -620,35 +634,35 @@
|
|
|
620
634
|
- 4518b6d: **BREAKING**
|
|
621
635
|
Updated how `createClient` infers the `PluvServer` type (again 🙁). The property to specify the type-inferred `PluvServer` type has been renamed to `types` from `infer`. `@pluv/client` now exports a function called `infer` that must now be used to construct the inferred `types` property. `infer` must be called before, and outside of `createClient` due to TypeScript inferrence limitations. See examples below:
|
|
622
636
|
|
|
623
|
-
|
|
624
|
-
|
|
637
|
+
```ts
|
|
638
|
+
// Before
|
|
625
639
|
|
|
626
|
-
|
|
627
|
-
|
|
640
|
+
import { createClient } from "@pluv/client";
|
|
641
|
+
import type { ioServer } from "../server/pluv";
|
|
628
642
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
643
|
+
const client = createClient({
|
|
644
|
+
// ...
|
|
645
|
+
infer: (i) => ({ io: i<typeof ioServer> }),
|
|
646
|
+
// ...
|
|
647
|
+
});
|
|
634
648
|
|
|
635
|
-
|
|
649
|
+
// After
|
|
636
650
|
|
|
637
|
-
|
|
638
|
-
|
|
651
|
+
import { createClient, infer } from "@pluv/client";
|
|
652
|
+
import type { ioServer } from "../server/pluv";
|
|
639
653
|
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
654
|
+
// Observe that `types` is initialized outside of `createClient`, instead of
|
|
655
|
+
// inline within the `createClient` function.`
|
|
656
|
+
const types = infer((i) => ({ io: i<typeof ioServer> }));
|
|
657
|
+
const client = createClient({
|
|
658
|
+
// ...
|
|
659
|
+
// Avoid calling `infer` inline within this function like in the commented
|
|
660
|
+
// example below:
|
|
661
|
+
// types: infer((i) => ({ io: i<typeof ioServer> })),
|
|
662
|
+
types,
|
|
663
|
+
// ...
|
|
664
|
+
});
|
|
665
|
+
```
|
|
652
666
|
|
|
653
667
|
### Patch Changes
|
|
654
668
|
|
|
@@ -674,8 +688,8 @@
|
|
|
674
688
|
### Patch Changes
|
|
675
689
|
|
|
676
690
|
- Updated dependencies [81cb692]
|
|
677
|
-
|
|
678
|
-
|
|
691
|
+
- @pluv/types@0.35.2
|
|
692
|
+
- @pluv/crdt@0.35.2
|
|
679
693
|
|
|
680
694
|
## 0.35.1
|
|
681
695
|
|
|
@@ -760,24 +774,23 @@
|
|
|
760
774
|
|
|
761
775
|
- b18230f: Add `register` helper to improve client initialization when hosted on pluv.io.
|
|
762
776
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
})
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
- @pluv/types@0.32.3
|
|
777
|
+
```ts
|
|
778
|
+
import { createClient, register } from "@pluv/client";
|
|
779
|
+
import type { ioServer } from "./server";
|
|
780
|
+
|
|
781
|
+
const client = createClient({
|
|
782
|
+
infer: (i) => ({ io: i<typeof ioServer> }),
|
|
783
|
+
// This includes `wsEndpoint` and therefore should no-longer be manually provided
|
|
784
|
+
...register({
|
|
785
|
+
// `authEndpoint` and `publicKey` are now required
|
|
786
|
+
authEndpoint: ({ room }) => `${process.env.API_URL}/api/room?room=${room}`,
|
|
787
|
+
publicKey: "pk_...",
|
|
788
|
+
}),
|
|
789
|
+
});
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
- @pluv/crdt@0.32.3
|
|
793
|
+
- @pluv/types@0.32.3
|
|
781
794
|
|
|
782
795
|
## 0.32.2
|
|
783
796
|
|
|
@@ -826,8 +839,8 @@
|
|
|
826
839
|
### Patch Changes
|
|
827
840
|
|
|
828
841
|
- cff933a: Add `publicKey` property to `createClient` for later usage ;)
|
|
829
|
-
|
|
830
|
-
|
|
842
|
+
- @pluv/crdt@0.30.0
|
|
843
|
+
- @pluv/types@0.30.0
|
|
831
844
|
|
|
832
845
|
## 0.29.0
|
|
833
846
|
|
|
@@ -849,124 +862,122 @@
|
|
|
849
862
|
|
|
850
863
|
- 19ed36c: **BREAKNG**
|
|
851
864
|
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
```ts
|
|
855
|
-
// Before
|
|
856
|
-
import { createClient } from "@pluv/client";
|
|
857
|
-
import { yjs } from "@pluv/crdt-yjs";
|
|
858
|
-
import { z } from "zod";
|
|
859
|
-
import type { ioServer } from "./server/ioServer";
|
|
860
|
-
|
|
861
|
-
const client = createClient<typeof ioServer>({
|
|
862
|
-
authEndpoint: ({ room }) => "MY_AUTH_URL",
|
|
863
|
-
wsEndpoint: ({ room }) => "MY_WEBSOCKET_URL",
|
|
864
|
-
});
|
|
865
|
-
|
|
866
|
-
client.createRoom("my-example-room", {
|
|
867
|
-
presence: z.object({
|
|
868
|
-
selectionId: z.string().nullish(),
|
|
869
|
-
}),
|
|
870
|
-
initialPresence: {
|
|
871
|
-
selectionId: null,
|
|
872
|
-
},
|
|
873
|
-
initialStorage: yjs.doc(() => ({
|
|
874
|
-
messages: yjs.array<string>([]),
|
|
875
|
-
})),
|
|
876
|
-
});
|
|
877
|
-
|
|
878
|
-
// After
|
|
879
|
-
const client = createClient({
|
|
880
|
-
authEndpoint: ({ room }) => "MY_AUTH_URL",
|
|
881
|
-
wsEndpoint: ({ room }) => "MY_WEBSOCKET_URL",
|
|
882
|
-
/**
|
|
883
|
-
* @description The ioServer type now needs to be inferred on this property
|
|
884
|
-
* instead of within the generic on `createClient`. This is because of
|
|
885
|
-
* limitations with TypeScript not yet supporting partial type-inference
|
|
886
|
-
* for generics. Ensure to no-loonger include any generics on `createClient`
|
|
887
|
-
*/
|
|
888
|
-
infer: (i) => ({ io: i<typeof ioServer> }),
|
|
889
|
-
// Now moved to `createClient` from `PluvClient.createRoom`
|
|
890
|
-
presence: z.object({
|
|
891
|
-
selectionId: z.string().nullish(),
|
|
892
|
-
}),
|
|
893
|
-
/**
|
|
894
|
-
* @description Now added to `createClient` to specify defaults for all
|
|
895
|
-
* rooms, and to infer types for storage. This value will be overwritten by
|
|
896
|
-
* `PluvClient.createRoom`.
|
|
897
|
-
*/
|
|
898
|
-
initialStorage: yjs.doc(() => ({
|
|
899
|
-
messages: yjs.array<string>([]),
|
|
900
|
-
})),
|
|
901
|
-
});
|
|
902
|
-
|
|
903
|
-
const room = client.createRoom("my-example-room", {
|
|
904
|
-
initialPresence: {
|
|
905
|
-
selectionId: null,
|
|
906
|
-
},
|
|
907
|
-
initialStorage: yjs.doc(() => ({
|
|
908
|
-
messages: yjs.array<string>([]),
|
|
909
|
-
})),
|
|
910
|
-
});
|
|
911
|
-
```
|
|
865
|
+
Updated `createClient` and `PluvClient.createRoom` object params to better support automatic type inference.
|
|
912
866
|
|
|
913
|
-
|
|
867
|
+
```ts
|
|
868
|
+
// Before
|
|
869
|
+
import { createClient } from "@pluv/client";
|
|
870
|
+
import { yjs } from "@pluv/crdt-yjs";
|
|
871
|
+
import { z } from "zod";
|
|
872
|
+
import type { ioServer } from "./server/ioServer";
|
|
914
873
|
|
|
915
|
-
|
|
874
|
+
const client = createClient<typeof ioServer>({
|
|
875
|
+
authEndpoint: ({ room }) => "MY_AUTH_URL",
|
|
876
|
+
wsEndpoint: ({ room }) => "MY_WEBSOCKET_URL",
|
|
877
|
+
});
|
|
916
878
|
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
multiply2: io.procedure
|
|
927
|
-
.input(z.object({ value: z.number() }))
|
|
928
|
-
.broadcast(({ value }) => ({
|
|
929
|
-
multiplied2: { value: value * 2 },
|
|
879
|
+
client.createRoom("my-example-room", {
|
|
880
|
+
presence: z.object({
|
|
881
|
+
selectionId: z.string().nullish(),
|
|
882
|
+
}),
|
|
883
|
+
initialPresence: {
|
|
884
|
+
selectionId: null,
|
|
885
|
+
},
|
|
886
|
+
initialStorage: yjs.doc(() => ({
|
|
887
|
+
messages: yjs.array<string>([]),
|
|
930
888
|
})),
|
|
931
|
-
})
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
889
|
+
});
|
|
890
|
+
|
|
891
|
+
// After
|
|
892
|
+
const client = createClient({
|
|
893
|
+
authEndpoint: ({ room }) => "MY_AUTH_URL",
|
|
894
|
+
wsEndpoint: ({ room }) => "MY_WEBSOCKET_URL",
|
|
895
|
+
/**
|
|
896
|
+
* @description The ioServer type now needs to be inferred on this property
|
|
897
|
+
* instead of within the generic on `createClient`. This is because of
|
|
898
|
+
* limitations with TypeScript not yet supporting partial type-inference
|
|
899
|
+
* for generics. Ensure to no-loonger include any generics on `createClient`
|
|
900
|
+
*/
|
|
901
|
+
infer: (i) => ({ io: i<typeof ioServer> }),
|
|
902
|
+
// Now moved to `createClient` from `PluvClient.createRoom`
|
|
903
|
+
presence: z.object({
|
|
904
|
+
selectionId: z.string().nullish(),
|
|
905
|
+
}),
|
|
906
|
+
/**
|
|
907
|
+
* @description Now added to `createClient` to specify defaults for all
|
|
908
|
+
* rooms, and to infer types for storage. This value will be overwritten by
|
|
909
|
+
* `PluvClient.createRoom`.
|
|
910
|
+
*/
|
|
911
|
+
initialStorage: yjs.doc(() => ({
|
|
912
|
+
messages: yjs.array<string>([]),
|
|
952
913
|
})),
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
.broadcast(({ value }) => ({
|
|
962
|
-
multiply2: { value: value - 5 },
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
const room = client.createRoom("my-example-room", {
|
|
917
|
+
initialPresence: {
|
|
918
|
+
selectionId: null,
|
|
919
|
+
},
|
|
920
|
+
initialStorage: yjs.doc(() => ({
|
|
921
|
+
messages: yjs.array<string>([]),
|
|
963
922
|
})),
|
|
964
|
-
})
|
|
965
|
-
|
|
966
|
-
|
|
923
|
+
});
|
|
924
|
+
```
|
|
925
|
+
|
|
926
|
+
### Patch Changes
|
|
967
927
|
|
|
968
|
-
|
|
969
|
-
|
|
928
|
+
- 19ed36c: Added client-side event router. This more-or-less mirrors the server-side event router. You can use both the server-side and client-side router simultaneously, but you should generally prefer only using one or the other.
|
|
929
|
+
|
|
930
|
+
```ts
|
|
931
|
+
// Backend Server
|
|
932
|
+
import { createIO } from "@pluv/io";
|
|
933
|
+
|
|
934
|
+
const io = createIO({
|
|
935
|
+
/* ... */
|
|
936
|
+
});
|
|
937
|
+
const ioServer = io.server({
|
|
938
|
+
router: io.router({
|
|
939
|
+
multiply2: io.procedure
|
|
940
|
+
.input(z.object({ value: z.number() }))
|
|
941
|
+
.broadcast(({ value }) => ({
|
|
942
|
+
multiplied2: { value: value * 2 },
|
|
943
|
+
})),
|
|
944
|
+
}),
|
|
945
|
+
});
|
|
946
|
+
|
|
947
|
+
// Frontend Client
|
|
948
|
+
import { createClient } from "@pluv/client";
|
|
949
|
+
|
|
950
|
+
const io = createClient({
|
|
951
|
+
/* ... */
|
|
952
|
+
});
|
|
953
|
+
|
|
954
|
+
const room = io.createRoom("my-example-room", {
|
|
955
|
+
// ...
|
|
956
|
+
router: io.router({
|
|
957
|
+
add5: io.procedure.input(z.object({ value: z.number() })).broadcast(({ value }) => ({
|
|
958
|
+
/**
|
|
959
|
+
* @description Because `ioServer` does not specify `added5`,
|
|
960
|
+
* this will be forwarded to connected peers.
|
|
961
|
+
*/
|
|
962
|
+
added5: { value: value + 5 },
|
|
963
|
+
})),
|
|
964
|
+
/**
|
|
965
|
+
* @description This is possible, but not recommended to do. Because
|
|
966
|
+
* `multiply2` is a procedure on `ioServer`, this will trigger the
|
|
967
|
+
* `multiply2` procedure on `ioServer`. Connected peers will not
|
|
968
|
+
* receive `multiply2`, but rather `multipled2`.
|
|
969
|
+
*/
|
|
970
|
+
subtract5Multiply2: io.procedure
|
|
971
|
+
.input(z.object({ value: z.number() }))
|
|
972
|
+
.broadcast(({ value }) => ({
|
|
973
|
+
multiply2: { value: value - 5 },
|
|
974
|
+
})),
|
|
975
|
+
}),
|
|
976
|
+
});
|
|
977
|
+
```
|
|
978
|
+
|
|
979
|
+
- @pluv/crdt@0.27.0
|
|
980
|
+
- @pluv/types@0.27.0
|
|
970
981
|
|
|
971
982
|
## 0.26.0
|
|
972
983
|
|
|
@@ -975,47 +986,47 @@
|
|
|
975
986
|
- 19e5dda: **BREAKING**
|
|
976
987
|
Update `authEndpoint` and `wsEndpoint` to now use a parameterized object that passes through additional data via a `metadata` property.
|
|
977
988
|
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
989
|
+
```tsx
|
|
990
|
+
// Before
|
|
991
|
+
|
|
992
|
+
import { env } from "./env";
|
|
993
|
+
import type { ioServer } from "./server";
|
|
994
|
+
|
|
995
|
+
const client = createClient<typeof ioServer>({
|
|
996
|
+
authEndpoint: (room: string) => `${env.API_URL}}/room/${room}`,
|
|
997
|
+
wsEndpoint: (room: string) => `${env.WS_URL}/room/${room}`,
|
|
998
|
+
});
|
|
999
|
+
|
|
1000
|
+
// After
|
|
1001
|
+
|
|
1002
|
+
const client = createClient<
|
|
1003
|
+
typeof ioServer,
|
|
1004
|
+
// Optional: You can specify types for metadata here. This is useful for Cloudflare Pages
|
|
1005
|
+
{ apiUrl: string; wsUrl: string }
|
|
1006
|
+
>({
|
|
1007
|
+
authEndpoint: ({ metadata, room }) => `${metadata.apiUrl}}/room/${room}`,
|
|
1008
|
+
wsEndpoint: ({ metadata, room }) => `${{ metadata.wsUrl }}/room/${room}`,
|
|
1009
|
+
});
|
|
1010
|
+
|
|
1011
|
+
client.createRoom("my-room", {
|
|
1012
|
+
// This property exists when the `metadata` generic type is defined above
|
|
1013
|
+
metadata: {
|
|
1014
|
+
apiUrl: "https://example.com/api",
|
|
1015
|
+
wsUrl: "wss://example.com/api",
|
|
1016
|
+
},
|
|
1017
|
+
// ...
|
|
1018
|
+
});
|
|
1019
|
+
|
|
1020
|
+
<PluvRoomProvider
|
|
1021
|
+
// This property exists when the `metadata` generic type is defined above
|
|
1022
|
+
metadata={{
|
|
1023
|
+
apiUrl: "https://example.com/api",
|
|
1024
|
+
wsUrl: "wss://example.com/api",
|
|
1025
|
+
}}
|
|
1026
|
+
>
|
|
1027
|
+
{/* ... */}
|
|
1028
|
+
</PluvRoomProvider>
|
|
1029
|
+
```
|
|
1019
1030
|
|
|
1020
1031
|
### Patch Changes
|
|
1021
1032
|
|
|
@@ -1062,8 +1073,8 @@
|
|
|
1062
1073
|
### Patch Changes
|
|
1063
1074
|
|
|
1064
1075
|
- ba299e2: Fixed "others" state in the PluvClient not getting cleared when the user's websocket connection is closed, creating "ghost users" during some reconnects.
|
|
1065
|
-
|
|
1066
|
-
|
|
1076
|
+
- @pluv/crdt@0.24.1
|
|
1077
|
+
- @pluv/types@0.24.1
|
|
1067
1078
|
|
|
1068
1079
|
## 0.24.0
|
|
1069
1080
|
|
|
@@ -1110,76 +1121,76 @@
|
|
|
1110
1121
|
|
|
1111
1122
|
- 9492085: **BREAKING**: `@pluv/crdt-yjs` and `@pluv/crdt-loro` have been updated so that the utilities to create shared-types/containers no-longer return a wrapper around the underlying shared-types and containers, but rather return the shared-types/containers directly.
|
|
1112
1123
|
|
|
1113
|
-
|
|
1124
|
+
This means that for methods such as `getStorage` from `@pluv/client` and `useStorage` from `@pluv/react`, the shared-types/containers are also returned instead of the wrapper types.
|
|
1114
1125
|
|
|
1115
|
-
|
|
1126
|
+
The motivation for these changes are so that pluv.io is supplementary to `yjs` and `loro-crdt`, instead of having these libraries be an internal implementation of pluv.io.
|
|
1116
1127
|
|
|
1117
|
-
|
|
1118
|
-
|
|
1128
|
+
```ts
|
|
1129
|
+
// Before
|
|
1119
1130
|
|
|
1120
|
-
|
|
1131
|
+
import { yjs } from "@pluv/crdt-yjs";
|
|
1121
1132
|
|
|
1122
|
-
|
|
1123
|
-
|
|
1133
|
+
yjs.array([]); // Returns CrdtYjsArray
|
|
1134
|
+
yjs.object([]); // Returns CrdtYjsObject
|
|
1124
1135
|
|
|
1125
|
-
|
|
1136
|
+
const room: PluvRoom = /* ... */;
|
|
1126
1137
|
|
|
1127
|
-
|
|
1138
|
+
room.getStorage("messages"); // Returns AbstractCrdtType
|
|
1128
1139
|
|
|
1129
|
-
|
|
1130
|
-
|
|
1140
|
+
const [, sharedType] = useStorage("messages"); // sharedType is an AbstractCrdtType
|
|
1141
|
+
```
|
|
1131
1142
|
|
|
1132
|
-
|
|
1133
|
-
|
|
1143
|
+
```ts
|
|
1144
|
+
// Now
|
|
1134
1145
|
|
|
1135
|
-
|
|
1146
|
+
import { yjs } from "@pluv/crdt-yjs";
|
|
1136
1147
|
|
|
1137
|
-
|
|
1138
|
-
|
|
1148
|
+
yjs.array([]); // Returns yjs.Array
|
|
1149
|
+
yjs.object([]); // Returns yjs.Map
|
|
1139
1150
|
|
|
1140
|
-
|
|
1151
|
+
const room: PluvRoom = /* ... */;
|
|
1141
1152
|
|
|
1142
|
-
|
|
1153
|
+
room.getStorage("messages"); // Returns yjs.AbstractType
|
|
1143
1154
|
|
|
1144
|
-
|
|
1145
|
-
|
|
1155
|
+
const [, sharedType] = useStorage("messages"); // sharedType is a yjs.AbstractType
|
|
1156
|
+
```
|
|
1146
1157
|
|
|
1147
|
-
|
|
1158
|
+
For `@pluv/crdt-loro` specifically, `@pluv/client` relies on [loro events and subscriptions](https://www.loro.dev/docs/tutorial/get_started#event) to detect changes. The `AbstractLoroCrdt` types previously called `Loro.commit` after each change as an abstraction, but now this no-longer happens. To ensure that changes to loro containers are properly handled in `@pluv/react`, make sure to commit your changes whenever possible:
|
|
1148
1159
|
|
|
1149
|
-
|
|
1150
|
-
|
|
1160
|
+
```ts
|
|
1161
|
+
// Before
|
|
1151
1162
|
|
|
1152
|
-
|
|
1163
|
+
const [data, container] = useStorage("messages");
|
|
1153
1164
|
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1165
|
+
// This automatically called Loro.commit under the hood and rerendered the page with updated data.
|
|
1166
|
+
container.push(loro.object({ name: "John Doe", age: 35 }));
|
|
1167
|
+
```
|
|
1157
1168
|
|
|
1158
|
-
|
|
1159
|
-
|
|
1169
|
+
```ts
|
|
1170
|
+
// Now
|
|
1160
1171
|
|
|
1161
|
-
|
|
1172
|
+
const [data, container] = useStorage("messages");
|
|
1162
1173
|
|
|
1163
|
-
|
|
1164
|
-
|
|
1174
|
+
const doc = useDoc();
|
|
1175
|
+
const transact = useTransact();
|
|
1165
1176
|
|
|
1166
|
-
|
|
1167
|
-
|
|
1177
|
+
// Updates need to be committed back to the doc whenever the changes need to be emitted to other users
|
|
1178
|
+
// The returned data also will not update until the changes are commited
|
|
1168
1179
|
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1180
|
+
// The two operations below are functionally equivalent
|
|
1181
|
+
transact(() => {
|
|
1182
|
+
container.push(loro.object({ name: "John Doe", age: 35 }));
|
|
1183
|
+
});
|
|
1173
1184
|
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1185
|
+
container.push(loro.object({ name: "John Doe", age: 35 }));
|
|
1186
|
+
doc.value.commit();
|
|
1187
|
+
```
|
|
1177
1188
|
|
|
1178
1189
|
### Patch Changes
|
|
1179
1190
|
|
|
1180
1191
|
- Updated dependencies [9492085]
|
|
1181
|
-
|
|
1182
|
-
|
|
1192
|
+
- @pluv/crdt@0.20.0
|
|
1193
|
+
- @pluv/types@0.20.0
|
|
1183
1194
|
|
|
1184
1195
|
## 0.19.0
|
|
1185
1196
|
|
|
@@ -1187,23 +1198,23 @@
|
|
|
1187
1198
|
|
|
1188
1199
|
- 137444b: Updated PluvRoom.updateMyPresence to allow passing in a callback function that exposes the previous presence value and returns a presence update.
|
|
1189
1200
|
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1201
|
+
```ts
|
|
1202
|
+
type Presence = {
|
|
1203
|
+
selectionId: string | null;
|
|
1204
|
+
};
|
|
1194
1205
|
|
|
1195
|
-
|
|
1196
|
-
|
|
1206
|
+
const room: PluvRoom = /* ... */;
|
|
1207
|
+
const newSelectionId: string | null = /* ... */;
|
|
1197
1208
|
|
|
1198
|
-
|
|
1209
|
+
room.updateMyPresence({ selectionId: newSelection });
|
|
1199
1210
|
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1211
|
+
// You can reference the previous presence and return a new presence based on it
|
|
1212
|
+
room.updateMyPresence((previousPresence) => ({ selectionId: newSelection ?? previousPresence.selectionId }));
|
|
1213
|
+
```
|
|
1203
1214
|
|
|
1204
1215
|
- f5e4370: Fix others' presence not getting tracked in PluvRoom when the user is unauthorized.
|
|
1205
|
-
|
|
1206
|
-
|
|
1216
|
+
- @pluv/crdt@0.19.0
|
|
1217
|
+
- @pluv/types@0.19.0
|
|
1207
1218
|
|
|
1208
1219
|
## 0.18.0
|
|
1209
1220
|
|
|
@@ -1211,151 +1222,151 @@
|
|
|
1211
1222
|
|
|
1212
1223
|
- 99b5ca9: ## Breaking Changes
|
|
1213
1224
|
|
|
1214
|
-
|
|
1225
|
+
- `@pluv/io` has been updated to introduce `PluvProcedure`, `PluvRouter` and `PluvServer`. This change is intended to improve the ergonomics of declaring events and simplifying inferences of event types.
|
|
1215
1226
|
|
|
1216
|
-
|
|
1227
|
+
### Before:
|
|
1217
1228
|
|
|
1218
|
-
|
|
1219
|
-
|
|
1229
|
+
```ts
|
|
1230
|
+
// backend/io.ts
|
|
1220
1231
|
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1232
|
+
import { createIO } from "@pluv/io";
|
|
1233
|
+
import { createPluvHandler, platformNode } from "@pluv/platform-node";
|
|
1234
|
+
import { z } from "zod";
|
|
1224
1235
|
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
})
|
|
1228
|
-
.event("SEND_MESSAGE", {
|
|
1229
|
-
input: z.object({ message: z.string() }),
|
|
1230
|
-
resolver: ({ message }) => ({ RECEIVE_MESSAGE: { message } }),
|
|
1236
|
+
export const io = createIO({
|
|
1237
|
+
platform: platformNode(),
|
|
1231
1238
|
})
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1239
|
+
.event("SEND_MESSAGE", {
|
|
1240
|
+
input: z.object({ message: z.string() }),
|
|
1241
|
+
resolver: ({ message }) => ({ RECEIVE_MESSAGE: { message } }),
|
|
1242
|
+
})
|
|
1243
|
+
.event("DOUBLE_VALUE", {
|
|
1244
|
+
input: z.object({ value: z.number() }),
|
|
1245
|
+
resolver: ({ value }) => ({ VALUE_DOUBLED: { value: value * 2 } }),
|
|
1246
|
+
});
|
|
1247
|
+
|
|
1248
|
+
const Pluv = createPluvHandler({
|
|
1249
|
+
io,
|
|
1250
|
+
/* ... */
|
|
1235
1251
|
});
|
|
1252
|
+
```
|
|
1236
1253
|
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
/* ... */
|
|
1240
|
-
});
|
|
1241
|
-
```
|
|
1242
|
-
|
|
1243
|
-
```ts
|
|
1244
|
-
// frontend/pluv.ts
|
|
1254
|
+
```ts
|
|
1255
|
+
// frontend/pluv.ts
|
|
1245
1256
|
|
|
1246
|
-
|
|
1247
|
-
|
|
1257
|
+
import { createClient } from "@pluv/react";
|
|
1258
|
+
import type { io } from "../backend/io";
|
|
1248
1259
|
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1260
|
+
const client = createClient<typeof io>({
|
|
1261
|
+
/* ... */
|
|
1262
|
+
});
|
|
1263
|
+
```
|
|
1253
1264
|
|
|
1254
|
-
|
|
1265
|
+
### Now:
|
|
1255
1266
|
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1267
|
+
```ts
|
|
1268
|
+
import { createIO } from "@pluv/io";
|
|
1269
|
+
import { createPluvHandler, platformNode } from "@pluv/platform-node";
|
|
1270
|
+
import { z } from "zod";
|
|
1260
1271
|
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1272
|
+
const io = createIO({
|
|
1273
|
+
platform: platformNode(),
|
|
1274
|
+
});
|
|
1264
1275
|
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1276
|
+
const router = io.router({
|
|
1277
|
+
SEND_MESSAGE: io.procedure
|
|
1278
|
+
.input(z.object({ message: z.string() }))
|
|
1279
|
+
.broadcast(({ message }) => ({
|
|
1280
|
+
RECEIVE_MESSAGE: { message },
|
|
1281
|
+
})),
|
|
1282
|
+
DOUBLE_VALUE: io.procedure
|
|
1283
|
+
.input(z.object({ value: z.number() }))
|
|
1284
|
+
.broadcast(({ value }) => ({
|
|
1285
|
+
VALUE_DOUBLED: { value: value * 2 },
|
|
1286
|
+
})),
|
|
1287
|
+
});
|
|
1277
1288
|
|
|
1278
|
-
|
|
1289
|
+
export const ioServer = io.server({ router });
|
|
1279
1290
|
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1291
|
+
const Pluv = createPluvHandler({
|
|
1292
|
+
io: ioServer, // <- This uses the PluvServer now
|
|
1293
|
+
/* ... */
|
|
1294
|
+
});
|
|
1295
|
+
```
|
|
1285
1296
|
|
|
1286
|
-
|
|
1287
|
-
|
|
1297
|
+
```ts
|
|
1298
|
+
// frontend/pluv.ts
|
|
1288
1299
|
|
|
1289
|
-
|
|
1290
|
-
|
|
1300
|
+
import { createClient } from "@pluv/react";
|
|
1301
|
+
import type { ioServer } from "../backend/io";
|
|
1291
1302
|
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1303
|
+
// This users the PluvServer type now
|
|
1304
|
+
const client = createClient<typeof ioServer>({
|
|
1305
|
+
/* ... */
|
|
1306
|
+
});
|
|
1307
|
+
```
|
|
1297
1308
|
|
|
1298
|
-
|
|
1309
|
+
- `PluvRouter` instances can also be merged via the `mergeRouters` method, which effectively performs an `Object.assign` of the events object and returns a new `PluvRouter` with the correct types:
|
|
1299
1310
|
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1311
|
+
```ts
|
|
1312
|
+
const router = io.mergeRouters(router1, router2);
|
|
1313
|
+
```
|
|
1303
1314
|
|
|
1304
1315
|
### Patch Changes
|
|
1305
1316
|
|
|
1306
1317
|
- 06c67be: Added broadcast proxy as a new way to broadcast events.
|
|
1307
1318
|
|
|
1308
|
-
|
|
1309
|
-
|
|
1319
|
+
```ts
|
|
1320
|
+
// backend
|
|
1310
1321
|
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1322
|
+
const router = io.router({
|
|
1323
|
+
SEND_MESSAGE: io.procedure
|
|
1324
|
+
.input(z.object({ message: z.string() }))
|
|
1325
|
+
.broadcast(({ message }) => ({ RECEIVE_MESSAGE: { message } })),
|
|
1326
|
+
});
|
|
1316
1327
|
|
|
1317
|
-
|
|
1318
|
-
|
|
1328
|
+
// frontend
|
|
1329
|
+
const client = createClient(/* ... */);
|
|
1319
1330
|
|
|
1320
|
-
|
|
1331
|
+
// Both of the examples below are equivalent.
|
|
1321
1332
|
|
|
1322
|
-
|
|
1333
|
+
client.broadcast("SEND_MESSAGE", { message: "Hello world~!" });
|
|
1323
1334
|
|
|
1324
|
-
|
|
1325
|
-
|
|
1335
|
+
client.broadcast.SEND_MESSAGE({ message: "Hello world~!" });
|
|
1336
|
+
```
|
|
1326
1337
|
|
|
1327
1338
|
- df1342c: Added event proxy as a new way to listen to events.
|
|
1328
1339
|
|
|
1329
|
-
|
|
1330
|
-
|
|
1340
|
+
```ts
|
|
1341
|
+
// backend
|
|
1331
1342
|
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1343
|
+
const router = io.router({
|
|
1344
|
+
SEND_MESSAGE: io.procedure
|
|
1345
|
+
.input(z.object({ message: z.string() }))
|
|
1346
|
+
.broadcast(({ message }) => ({ RECEIVE_MESSAGE: { message } })),
|
|
1347
|
+
});
|
|
1337
1348
|
|
|
1338
|
-
|
|
1339
|
-
|
|
1349
|
+
// frontend
|
|
1350
|
+
const client = createClient(/* ... */);
|
|
1340
1351
|
|
|
1341
|
-
|
|
1352
|
+
// Both of the examples below are equivalent.
|
|
1342
1353
|
|
|
1343
|
-
|
|
1344
|
-
|
|
1354
|
+
client.event("RECEIVE_MESSAGE", ({ data }) => {
|
|
1355
|
+
const { message } = data;
|
|
1345
1356
|
|
|
1346
|
-
|
|
1347
|
-
|
|
1357
|
+
console.log(message);
|
|
1358
|
+
});
|
|
1348
1359
|
|
|
1349
|
-
|
|
1350
|
-
|
|
1360
|
+
client.event.RECEIVE_MESSAGE(({ data }) => {
|
|
1361
|
+
const { message } = data;
|
|
1351
1362
|
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1363
|
+
console.log(message);
|
|
1364
|
+
});
|
|
1365
|
+
```
|
|
1355
1366
|
|
|
1356
1367
|
- Updated dependencies [99b5ca9]
|
|
1357
|
-
|
|
1358
|
-
|
|
1368
|
+
- @pluv/types@0.18.0
|
|
1369
|
+
- @pluv/crdt@0.18.0
|
|
1359
1370
|
|
|
1360
1371
|
## 0.17.3
|
|
1361
1372
|
|
|
@@ -1383,8 +1394,8 @@
|
|
|
1383
1394
|
### Patch Changes
|
|
1384
1395
|
|
|
1385
1396
|
- Updated dependencies [507bc00]
|
|
1386
|
-
|
|
1387
|
-
|
|
1397
|
+
- @pluv/types@0.17.0
|
|
1398
|
+
- @pluv/crdt@0.17.0
|
|
1388
1399
|
|
|
1389
1400
|
## 0.16.3
|
|
1390
1401
|
|
|
@@ -1413,145 +1424,143 @@
|
|
|
1413
1424
|
|
|
1414
1425
|
- 4280220: ## Breaking Changes
|
|
1415
1426
|
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1427
|
+
- Storage types are now kept on the root of the document.
|
|
1428
|
+
- 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.
|
|
1429
|
+
- `@pluv/client` and `@pluv/react` no-longer re-export `@pluv/crdt-yjs`. This package will now need to be installed separately.
|
|
1430
|
+
|
|
1431
|
+
```bash
|
|
1432
|
+
# if installing @pluv/client
|
|
1433
|
+
npm install @pluv/client @pluv/crdt-yjs
|
|
1434
|
+
# if installing @pluv/react
|
|
1435
|
+
npm install @pluv/react @pluv/crdt-yjs
|
|
1436
|
+
```
|
|
1437
|
+
|
|
1438
|
+
```ts
|
|
1439
|
+
// Before:
|
|
1440
|
+
import { createClient, y } from "@pluv/client";
|
|
1441
|
+
// After:
|
|
1442
|
+
import { createClient } from "@pluv/client";
|
|
1443
|
+
import { yjs } from "@pluv/crdt-yjs"; // y renamed to yjs
|
|
1444
|
+
```
|
|
1445
|
+
|
|
1446
|
+
- The `y` import has been renamed to `yjs`.
|
|
1447
|
+
```ts
|
|
1448
|
+
// Before:
|
|
1449
|
+
import { y } from "@pluv/crdt-yjs";
|
|
1450
|
+
// After:
|
|
1451
|
+
import { yjs } from "@pluv/crdt-yjs";
|
|
1452
|
+
```
|
|
1453
|
+
- `@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`.
|
|
1454
|
+
|
|
1455
|
+
```ts
|
|
1456
|
+
// Before:
|
|
1457
|
+
import { y } from "@pluv/crdt-yjs";
|
|
1458
|
+
import type { Array as YArray, Map as YMap } from "yjs";
|
|
1459
|
+
|
|
1460
|
+
const array: YArray<YMap<{ message: string }>> = y.array([y.object({ message: "Hello" })]);
|
|
1461
|
+
|
|
1462
|
+
array.push([y.object({ message: "World!" })]);
|
|
1463
|
+
|
|
1464
|
+
// After:
|
|
1465
|
+
import type { CrdtYjsArray, CrdtYjsObject } from "@pluv/crdt-yjs";
|
|
1466
|
+
import { yjs } from "@pluv/crdt-yjs";
|
|
1467
|
+
import type { Array as YArray } from "yjs";
|
|
1468
|
+
|
|
1469
|
+
const array: CrdtYjsArray<CrdtYjsObject<{ message: string }>> = yjs.array([
|
|
1470
|
+
yjs.object({ message: "Hello" }),
|
|
1471
|
+
]);
|
|
1472
|
+
|
|
1473
|
+
array.push(yjs.object({ message: "World!" }));
|
|
1474
|
+
|
|
1475
|
+
// use .value to get the underlying yjs type
|
|
1476
|
+
const yarray: YArray<YMap<{ message: string }>> = array.value;
|
|
1477
|
+
```
|
|
1478
|
+
|
|
1479
|
+
- `initialStorage` must now use the `doc` function from `@pluv/crdt-yjs` to be defined. This also affects `@pluv/react`.
|
|
1480
|
+
|
|
1481
|
+
```ts
|
|
1482
|
+
// Before:
|
|
1483
|
+
import { createClient, y } from "@pluv/client";
|
|
1484
|
+
|
|
1485
|
+
const client = createClient({
|
|
1486
|
+
/* ... */
|
|
1487
|
+
});
|
|
1488
|
+
|
|
1489
|
+
client.createRoom({
|
|
1490
|
+
// ...
|
|
1491
|
+
initialStorage: () => ({
|
|
1492
|
+
messages: y.array([y.object({ message: "Hello world!" })]),
|
|
1493
|
+
}),
|
|
1494
|
+
});
|
|
1495
|
+
|
|
1496
|
+
// After:
|
|
1497
|
+
import { createClient } from "@pluv/client";
|
|
1498
|
+
// This is now imported separately
|
|
1499
|
+
import { yjs } from "@pluv/crdt-yjs";
|
|
1500
|
+
|
|
1501
|
+
const client = createClient({
|
|
1502
|
+
/* ... */
|
|
1503
|
+
});
|
|
1504
|
+
|
|
1505
|
+
client.createRoom({
|
|
1506
|
+
// ...
|
|
1507
|
+
initialStorage: yjs.doc(() => ({
|
|
1508
|
+
messages: yjs.array([yjs.object({ message: "Hello world!" })]),
|
|
1509
|
+
})),
|
|
1510
|
+
});
|
|
1511
|
+
```
|
|
1512
|
+
|
|
1513
|
+
- `@pluv/client` can now instead use [loro](https://github.com/loro-dev/loro) instead of [yjs](https://github.com/yjs/yjs).
|
|
1514
|
+
```bash
|
|
1515
|
+
npm install @pluv/client @pluv/crdt-loro loro-crdt
|
|
1516
|
+
```
|
|
1517
|
+
- 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.
|
|
1518
|
+
|
|
1519
|
+
```ts
|
|
1520
|
+
import { loro } from "@pluv/crdt-loro";
|
|
1521
|
+
import { yjs } from "@pluv/crdt-yjs";
|
|
1522
|
+
import { createIO } from "@pluv/io";
|
|
1523
|
+
|
|
1524
|
+
const io = createIO({
|
|
1525
|
+
// ...
|
|
1526
|
+
// If using loro
|
|
1527
|
+
crdt: loro,
|
|
1528
|
+
// If using yjs
|
|
1529
|
+
crdt: yjs,
|
|
1530
|
+
});
|
|
1531
|
+
```
|
|
1532
|
+
|
|
1533
|
+
- `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`.
|
|
1534
|
+
|
|
1535
|
+
```ts
|
|
1536
|
+
// Before:
|
|
1537
|
+
import { Doc as YDoc } from "yjs";
|
|
1538
|
+
|
|
1539
|
+
const room: PluvRoom = client.createRoom({
|
|
1540
|
+
/* ... */
|
|
1541
|
+
});
|
|
1448
1542
|
|
|
1449
|
-
|
|
1450
|
-
y.object({ message: "Hello" }),
|
|
1451
|
-
]);
|
|
1543
|
+
const doc: YDoc = room.getDoc();
|
|
1452
1544
|
|
|
1453
|
-
|
|
1545
|
+
// After:
|
|
1546
|
+
import { CrdtYjsDoc } from "@pluv/crdt-yjs";
|
|
1547
|
+
import { Doc as YDoc } from "yjs";
|
|
1454
1548
|
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
import type { Array as YArray } from "yjs";
|
|
1549
|
+
const room: PluvRoom = client.createRoom({
|
|
1550
|
+
/* ... */
|
|
1551
|
+
});
|
|
1459
1552
|
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1553
|
+
const doc: CrdtYjsDoc<any> = room.getDoc();
|
|
1554
|
+
const ydoc: YDoc = doc.value;
|
|
1555
|
+
```
|
|
1463
1556
|
|
|
1464
|
-
|
|
1557
|
+
- `@pluv/client` and `@pluv/react` now may return `null` when retrieving storage while storage is being initialized.
|
|
1465
1558
|
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
```
|
|
1559
|
+
```ts
|
|
1560
|
+
const sharedType = room.getStorage("messages"); // This may be null
|
|
1469
1561
|
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
```ts
|
|
1473
|
-
// Before:
|
|
1474
|
-
import { createClient, y } from "@pluv/client";
|
|
1475
|
-
|
|
1476
|
-
const client = createClient({
|
|
1477
|
-
/* ... */
|
|
1478
|
-
});
|
|
1479
|
-
|
|
1480
|
-
client.createRoom({
|
|
1481
|
-
// ...
|
|
1482
|
-
initialStorage: () => ({
|
|
1483
|
-
messages: y.array([y.object({ message: "Hello world!" })]),
|
|
1484
|
-
}),
|
|
1485
|
-
});
|
|
1486
|
-
|
|
1487
|
-
// After:
|
|
1488
|
-
import { createClient } from "@pluv/client";
|
|
1489
|
-
// This is now imported separately
|
|
1490
|
-
import { yjs } from "@pluv/crdt-yjs";
|
|
1491
|
-
|
|
1492
|
-
const client = createClient({
|
|
1493
|
-
/* ... */
|
|
1494
|
-
});
|
|
1495
|
-
|
|
1496
|
-
client.createRoom({
|
|
1497
|
-
// ...
|
|
1498
|
-
initialStorage: yjs.doc(() => ({
|
|
1499
|
-
messages: yjs.array([yjs.object({ message: "Hello world!" })]),
|
|
1500
|
-
})),
|
|
1501
|
-
});
|
|
1502
|
-
```
|
|
1503
|
-
|
|
1504
|
-
- `@pluv/client` can now instead use [loro](https://github.com/loro-dev/loro) instead of [yjs](https://github.com/yjs/yjs).
|
|
1505
|
-
```bash
|
|
1506
|
-
npm install @pluv/client @pluv/crdt-loro loro-crdt
|
|
1507
|
-
```
|
|
1508
|
-
- 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.
|
|
1509
|
-
|
|
1510
|
-
```ts
|
|
1511
|
-
import { loro } from "@pluv/crdt-loro";
|
|
1512
|
-
import { yjs } from "@pluv/crdt-yjs";
|
|
1513
|
-
import { createIO } from "@pluv/io";
|
|
1514
|
-
|
|
1515
|
-
const io = createIO({
|
|
1516
|
-
// ...
|
|
1517
|
-
// If using loro
|
|
1518
|
-
crdt: loro,
|
|
1519
|
-
// If using yjs
|
|
1520
|
-
crdt: yjs,
|
|
1521
|
-
});
|
|
1522
|
-
```
|
|
1523
|
-
|
|
1524
|
-
- `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`.
|
|
1525
|
-
|
|
1526
|
-
```ts
|
|
1527
|
-
// Before:
|
|
1528
|
-
import { Doc as YDoc } from "yjs";
|
|
1529
|
-
|
|
1530
|
-
const room: PluvRoom = client.createRoom({
|
|
1531
|
-
/* ... */
|
|
1532
|
-
});
|
|
1533
|
-
|
|
1534
|
-
const doc: YDoc = room.getDoc();
|
|
1535
|
-
|
|
1536
|
-
// After:
|
|
1537
|
-
import { CrdtYjsDoc } from "@pluv/crdt-yjs";
|
|
1538
|
-
import { Doc as YDoc } from "yjs";
|
|
1539
|
-
|
|
1540
|
-
const room: PluvRoom = client.createRoom({
|
|
1541
|
-
/* ... */
|
|
1542
|
-
});
|
|
1543
|
-
|
|
1544
|
-
const doc: CrdtYjsDoc<any> = room.getDoc();
|
|
1545
|
-
const ydoc: YDoc = doc.value;
|
|
1546
|
-
```
|
|
1547
|
-
|
|
1548
|
-
- `@pluv/client` and `@pluv/react` now may return `null` when retrieving storage while storage is being initialized.
|
|
1549
|
-
|
|
1550
|
-
```ts
|
|
1551
|
-
const sharedType = room.getStorage("messages"); // This may be null
|
|
1552
|
-
|
|
1553
|
-
const [data, sharedType] = useStorage("messages"); // data and sharedType may both be null
|
|
1554
|
-
```
|
|
1562
|
+
const [data, sharedType] = useStorage("messages"); // data and sharedType may both be null
|
|
1563
|
+
```
|
|
1555
1564
|
|
|
1556
1565
|
### Patch Changes
|
|
1557
1566
|
|
|
@@ -1585,15 +1594,15 @@
|
|
|
1585
1594
|
|
|
1586
1595
|
- 1126215: Added `getDoc` on `PluvRoom` to access the root Yjs doc.
|
|
1587
1596
|
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1597
|
+
```ts
|
|
1598
|
+
import { createClient } from "@pluv/client";
|
|
1599
|
+
import type { Doc } from "yjs";
|
|
1591
1600
|
|
|
1592
|
-
|
|
1593
|
-
|
|
1601
|
+
const client = createClient(/* ... */);
|
|
1602
|
+
const room = client.createRoom(/* ... */);
|
|
1594
1603
|
|
|
1595
|
-
|
|
1596
|
-
|
|
1604
|
+
const doc: Doc = room.getDoc();
|
|
1605
|
+
```
|
|
1597
1606
|
|
|
1598
1607
|
### Patch Changes
|
|
1599
1608
|
|
|
@@ -1606,8 +1615,8 @@
|
|
|
1606
1615
|
|
|
1607
1616
|
- da9f600: Upgraded dependencies
|
|
1608
1617
|
- Updated dependencies [da9f600]
|
|
1609
|
-
|
|
1610
|
-
|
|
1618
|
+
- @pluv/crdt-yjs@0.12.3
|
|
1619
|
+
- @pluv/types@0.12.3
|
|
1611
1620
|
|
|
1612
1621
|
## 0.12.2
|
|
1613
1622
|
|
|
@@ -1620,8 +1629,8 @@
|
|
|
1620
1629
|
### Patch Changes
|
|
1621
1630
|
|
|
1622
1631
|
- cae08aa: Updated storage from `getStorage` to never return null
|
|
1623
|
-
|
|
1624
|
-
|
|
1632
|
+
- @pluv/crdt-yjs@0.12.1
|
|
1633
|
+
- @pluv/types@0.12.1
|
|
1625
1634
|
|
|
1626
1635
|
## 0.12.0
|
|
1627
1636
|
|
|
@@ -1629,239 +1638,238 @@
|
|
|
1629
1638
|
|
|
1630
1639
|
- 436040b: Added ability to undo and redo changes to storage.
|
|
1631
1640
|
|
|
1632
|
-
|
|
1641
|
+
## @pluv/crdt-yjs
|
|
1642
|
+
|
|
1643
|
+
`@pluv/crdt-yjs` now exposes 5 new methods: `canRedo`, `canUndo`, `redo`, `undo` and `trackOrigins`.
|
|
1644
|
+
|
|
1645
|
+
Refer to the code-example below to better understand how to undo and redo with your doc.
|
|
1646
|
+
|
|
1647
|
+
```ts
|
|
1648
|
+
// Example
|
|
1649
|
+
import { array, doc } from "@pluv/crdt-yjs";
|
|
1633
1650
|
|
|
1634
|
-
|
|
1651
|
+
// Create your doc with your shared-types
|
|
1652
|
+
const myDoc = doc({
|
|
1653
|
+
messages: array<string>([]),
|
|
1654
|
+
});
|
|
1635
1655
|
|
|
1636
|
-
|
|
1656
|
+
/**
|
|
1657
|
+
* @description Track origins to enable undos and redos for your document.
|
|
1658
|
+
* trackOrigins must be called before any storage mutations, to enable those
|
|
1659
|
+
* mutations to be undone/redone.
|
|
1660
|
+
*/
|
|
1661
|
+
myDoc.trackOrigins({
|
|
1662
|
+
/**
|
|
1663
|
+
* @description This is the same `captureTimeout` option from yjs's UndoManager.
|
|
1664
|
+
* This specifies a number in ms, during which edits are merged together to be
|
|
1665
|
+
* undone together. Set this to 0, to track each transacted change individually.
|
|
1666
|
+
* @see (@link https://docs.yjs.dev/api/undo-manager)
|
|
1667
|
+
* @default 500
|
|
1668
|
+
*/
|
|
1669
|
+
captureTimeout: 500,
|
|
1670
|
+
/**
|
|
1671
|
+
* @desription This is the same `trackedOrigins` option from yjs's UndoManager.
|
|
1672
|
+
* This specifies transaction origins (strings only) to filter which transactions
|
|
1673
|
+
* can be undone.
|
|
1674
|
+
* @see (@link https://docs.yjs.dev/api/undo-manager)
|
|
1675
|
+
* @default undefined
|
|
1676
|
+
*/
|
|
1677
|
+
trackedOrigins: ["user-123"],
|
|
1678
|
+
});
|
|
1637
1679
|
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1680
|
+
/**
|
|
1681
|
+
* @description Check whether calling undo will mutate storage
|
|
1682
|
+
* @returns boolean
|
|
1683
|
+
*/
|
|
1684
|
+
myDoc.canUndo();
|
|
1685
|
+
/**
|
|
1686
|
+
* @description Check whether calling redo will mutate storage
|
|
1687
|
+
* @returns boolean
|
|
1688
|
+
*/
|
|
1689
|
+
myDoc.canRedo();
|
|
1641
1690
|
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1691
|
+
// Perform a storage mutation within a transaction so that it can be affected
|
|
1692
|
+
// by undo/redo operations.
|
|
1693
|
+
myDoc.transact(() => {
|
|
1694
|
+
myDoc.get("messages").push(["hello world!"]);
|
|
1695
|
+
}, "user-123");
|
|
1696
|
+
|
|
1697
|
+
/**
|
|
1698
|
+
* @description Undoes the last valid mutation to storage
|
|
1699
|
+
*/
|
|
1700
|
+
myDoc.undo();
|
|
1701
|
+
|
|
1702
|
+
/**
|
|
1703
|
+
* @description Re-applies the last undone mutation to storage
|
|
1704
|
+
*/
|
|
1705
|
+
myDoc.redo();
|
|
1706
|
+
```
|
|
1707
|
+
|
|
1708
|
+
## @pluv/client
|
|
1709
|
+
|
|
1710
|
+
`@pluv/client`'s `PluvRoom` and `MockedRoom` now exposes 5 new methods: `canRedo`, `canUndo`, `redo`, `undo` and `transact`.
|
|
1711
|
+
|
|
1712
|
+
Refer to the code-example below to better understand how to undo and redo with your `PluvRoom`.
|
|
1713
|
+
|
|
1714
|
+
```ts
|
|
1715
|
+
import { createClient, y } from "@pluv/client";
|
|
1716
|
+
|
|
1717
|
+
const client = createClient({});
|
|
1718
|
+
|
|
1719
|
+
/**
|
|
1720
|
+
* @description When a room is created, undo/redo will automatically
|
|
1721
|
+
* be configured to filter for changes made by the connected user
|
|
1722
|
+
* (so that users only undo/redo their changes).
|
|
1723
|
+
*/
|
|
1724
|
+
const room = client.createRoom("my-room", {
|
|
1725
|
+
initialStorage: () => ({
|
|
1726
|
+
messages: y.array<string>([]),
|
|
1727
|
+
}),
|
|
1728
|
+
/**
|
|
1729
|
+
* @description This is the same `captureTimeout` option from yjs's UndoManager.
|
|
1730
|
+
* This specifies a number in ms, during which edits are merged together to be
|
|
1731
|
+
* undone together. Set this to 0, to track each transacted change individually.
|
|
1732
|
+
* @see (@link https://docs.yjs.dev/api/undo-manager)
|
|
1733
|
+
* @default 500
|
|
1734
|
+
*/
|
|
1735
|
+
captureTimeout: 500,
|
|
1736
|
+
/**
|
|
1737
|
+
* @desription This is the same `trackedOrigins` option from yjs's UndoManager.
|
|
1738
|
+
* This specifies transaction origins (strings only) to filter which transactions
|
|
1739
|
+
* can be undone.
|
|
1740
|
+
* When omitted, the user's connection id will be tracked. When provided,
|
|
1741
|
+
* specifies additional tracked origins besides the user's connection id.
|
|
1742
|
+
* @see (@link https://docs.yjs.dev/api/undo-manager)
|
|
1743
|
+
* @default undefined
|
|
1744
|
+
*/
|
|
1745
|
+
trackedOrigins: ["user-123"],
|
|
1746
|
+
});
|
|
1646
1747
|
|
|
1647
|
-
/**
|
|
1648
|
-
* @description Track origins to enable undos and redos for your document.
|
|
1649
|
-
* trackOrigins must be called before any storage mutations, to enable those
|
|
1650
|
-
* mutations to be undone/redone.
|
|
1651
|
-
*/
|
|
1652
|
-
myDoc.trackOrigins({
|
|
1653
1748
|
/**
|
|
1654
|
-
* @description
|
|
1655
|
-
*
|
|
1656
|
-
* undone together. Set this to 0, to track each transacted change individually.
|
|
1657
|
-
* @see (@link https://docs.yjs.dev/api/undo-manager)
|
|
1658
|
-
* @default 500
|
|
1749
|
+
* @description Check whether calling undo will mutate storage
|
|
1750
|
+
* @returns boolean
|
|
1659
1751
|
*/
|
|
1660
|
-
|
|
1752
|
+
room.canUndo();
|
|
1661
1753
|
/**
|
|
1662
|
-
* @
|
|
1663
|
-
*
|
|
1664
|
-
* can be undone.
|
|
1665
|
-
* @see (@link https://docs.yjs.dev/api/undo-manager)
|
|
1666
|
-
* @default undefined
|
|
1754
|
+
* @description Check whether calling redo will mutate storage
|
|
1755
|
+
* @returns boolean
|
|
1667
1756
|
*/
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
/**
|
|
1672
|
-
* @description Check whether calling undo will mutate storage
|
|
1673
|
-
* @returns boolean
|
|
1674
|
-
*/
|
|
1675
|
-
myDoc.canUndo();
|
|
1676
|
-
/**
|
|
1677
|
-
* @description Check whether calling redo will mutate storage
|
|
1678
|
-
* @returns boolean
|
|
1679
|
-
*/
|
|
1680
|
-
myDoc.canRedo();
|
|
1681
|
-
|
|
1682
|
-
// Perform a storage mutation within a transaction so that it can be affected
|
|
1683
|
-
// by undo/redo operations.
|
|
1684
|
-
myDoc.transact(() => {
|
|
1685
|
-
myDoc.get("messages").push(["hello world!"]);
|
|
1686
|
-
}, "user-123");
|
|
1687
|
-
|
|
1688
|
-
/**
|
|
1689
|
-
* @description Undoes the last valid mutation to storage
|
|
1690
|
-
*/
|
|
1691
|
-
myDoc.undo();
|
|
1692
|
-
|
|
1693
|
-
/**
|
|
1694
|
-
* @description Re-applies the last undone mutation to storage
|
|
1695
|
-
*/
|
|
1696
|
-
myDoc.redo();
|
|
1697
|
-
```
|
|
1698
|
-
|
|
1699
|
-
## @pluv/client
|
|
1700
|
-
|
|
1701
|
-
`@pluv/client`'s `PluvRoom` and `MockedRoom` now exposes 5 new methods: `canRedo`, `canUndo`, `redo`, `undo` and `transact`.
|
|
1702
|
-
|
|
1703
|
-
Refer to the code-example below to better understand how to undo and redo with your `PluvRoom`.
|
|
1704
|
-
|
|
1705
|
-
```ts
|
|
1706
|
-
import { createClient, y } from "@pluv/client";
|
|
1707
|
-
|
|
1708
|
-
const client = createClient({});
|
|
1709
|
-
|
|
1710
|
-
/**
|
|
1711
|
-
* @description When a room is created, undo/redo will automatically
|
|
1712
|
-
* be configured to filter for changes made by the connected user
|
|
1713
|
-
* (so that users only undo/redo their changes).
|
|
1714
|
-
*/
|
|
1715
|
-
const room = client.createRoom("my-room", {
|
|
1716
|
-
initialStorage: () => ({
|
|
1717
|
-
messages: y.array<string>([]),
|
|
1718
|
-
}),
|
|
1757
|
+
room.canRedo();
|
|
1758
|
+
|
|
1719
1759
|
/**
|
|
1720
|
-
* @description
|
|
1721
|
-
*
|
|
1722
|
-
*
|
|
1723
|
-
*
|
|
1724
|
-
*
|
|
1760
|
+
* @description Calling transact will enable a storage mutation to be undone/redone.
|
|
1761
|
+
* When called without an origin, the origin will default to the user's connection
|
|
1762
|
+
* id.
|
|
1763
|
+
*
|
|
1764
|
+
* You can specify a 2nd parameter to transact with a different transaction origin.
|
|
1725
1765
|
*/
|
|
1726
|
-
|
|
1766
|
+
room.transact(() => {
|
|
1767
|
+
room.get("messages").push(["hello world!"]);
|
|
1768
|
+
});
|
|
1769
|
+
|
|
1770
|
+
// This will also be undoable because `"user-123"` is a tracked origin.
|
|
1771
|
+
room.transact(() => {
|
|
1772
|
+
room.get("messages").push(["hello world!"]);
|
|
1773
|
+
}, "user-123");
|
|
1774
|
+
|
|
1727
1775
|
/**
|
|
1728
|
-
* @
|
|
1729
|
-
* This specifies transaction origins (strings only) to filter which transactions
|
|
1730
|
-
* can be undone.
|
|
1731
|
-
* When omitted, the user's connection id will be tracked. When provided,
|
|
1732
|
-
* specifies additional tracked origins besides the user's connection id.
|
|
1733
|
-
* @see (@link https://docs.yjs.dev/api/undo-manager)
|
|
1734
|
-
* @default undefined
|
|
1776
|
+
* @description Undoes the last valid mutation to storage
|
|
1735
1777
|
*/
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
Refer to the code-example below to better understand how to undo and redo with your `createRoomBundle`.
|
|
1782
|
-
|
|
1783
|
-
```tsx
|
|
1784
|
-
import { createBundle, createClient, y } from "@pluv/react";
|
|
1785
|
-
import { type io } from "./io";
|
|
1786
|
-
|
|
1787
|
-
const client = createClient<typeof io>();
|
|
1788
|
-
|
|
1789
|
-
const { createRoomBundle } = createBundle(client);
|
|
1790
|
-
|
|
1791
|
-
const { useCanRedo, useCanUndo, useRedo, useStorage, useTransact, useUndo } =
|
|
1792
|
-
createRoomBundle({
|
|
1793
|
-
initialStorage: () => ({
|
|
1794
|
-
messages: y.array<string>([]),
|
|
1795
|
-
}),
|
|
1796
|
-
/**
|
|
1797
|
-
* @description This is the same `captureTimeout` option from yjs's UndoManager.
|
|
1798
|
-
* This specifies a number in ms, during which edits are merged together to be
|
|
1799
|
-
* undone together. Set this to 0, to track each transacted change individually.
|
|
1800
|
-
* @see (@link https://docs.yjs.dev/api/undo-manager)
|
|
1801
|
-
* @default 500
|
|
1802
|
-
*/
|
|
1803
|
-
captureTimeout: 500,
|
|
1804
|
-
/**
|
|
1805
|
-
* @desription This is the same `trackedOrigins` option from yjs's UndoManager.
|
|
1806
|
-
* This specifies transaction origins (strings only) to filter which transactions
|
|
1807
|
-
* can be undone.
|
|
1808
|
-
* When omitted, the user's connection id will be tracked. When provided,
|
|
1809
|
-
* specifies additional tracked origins besides the user's connection id.
|
|
1810
|
-
* @see (@link https://docs.yjs.dev/api/undo-manager)
|
|
1811
|
-
* @default undefined
|
|
1812
|
-
*/
|
|
1813
|
-
trackedOrigins: ["user-123"],
|
|
1778
|
+
room.undo();
|
|
1779
|
+
|
|
1780
|
+
/**
|
|
1781
|
+
* @description Re-applies the last undone mutation to storage
|
|
1782
|
+
*/
|
|
1783
|
+
room.redo();
|
|
1784
|
+
```
|
|
1785
|
+
|
|
1786
|
+
## @pluv/react
|
|
1787
|
+
|
|
1788
|
+
`@pluv/react`'s `createRoomBundle` now exposes 5 new react hooks: `useCanRedo`, `useCanUndo`, `useRedo`, `useUndo` and `useTransact`.
|
|
1789
|
+
|
|
1790
|
+
Refer to the code-example below to better understand how to undo and redo with your `createRoomBundle`.
|
|
1791
|
+
|
|
1792
|
+
```tsx
|
|
1793
|
+
import { createBundle, createClient, y } from "@pluv/react";
|
|
1794
|
+
import { type io } from "./io";
|
|
1795
|
+
|
|
1796
|
+
const client = createClient<typeof io>();
|
|
1797
|
+
|
|
1798
|
+
const { createRoomBundle } = createBundle(client);
|
|
1799
|
+
|
|
1800
|
+
const { useCanRedo, useCanUndo, useRedo, useStorage, useTransact, useUndo } = createRoomBundle({
|
|
1801
|
+
initialStorage: () => ({
|
|
1802
|
+
messages: y.array<string>([]),
|
|
1803
|
+
}),
|
|
1804
|
+
/**
|
|
1805
|
+
* @description This is the same `captureTimeout` option from yjs's UndoManager.
|
|
1806
|
+
* This specifies a number in ms, during which edits are merged together to be
|
|
1807
|
+
* undone together. Set this to 0, to track each transacted change individually.
|
|
1808
|
+
* @see (@link https://docs.yjs.dev/api/undo-manager)
|
|
1809
|
+
* @default 500
|
|
1810
|
+
*/
|
|
1811
|
+
captureTimeout: 500,
|
|
1812
|
+
/**
|
|
1813
|
+
* @desription This is the same `trackedOrigins` option from yjs's UndoManager.
|
|
1814
|
+
* This specifies transaction origins (strings only) to filter which transactions
|
|
1815
|
+
* can be undone.
|
|
1816
|
+
* When omitted, the user's connection id will be tracked. When provided,
|
|
1817
|
+
* specifies additional tracked origins besides the user's connection id.
|
|
1818
|
+
* @see (@link https://docs.yjs.dev/api/undo-manager)
|
|
1819
|
+
* @default undefined
|
|
1820
|
+
*/
|
|
1821
|
+
trackedOrigins: ["user-123"],
|
|
1814
1822
|
});
|
|
1815
1823
|
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
+
/**
|
|
1825
|
+
* @description Check whether calling undo will mutate storage
|
|
1826
|
+
*/
|
|
1827
|
+
const canUndo: boolean = useCanUndo();
|
|
1828
|
+
/**
|
|
1829
|
+
* @description Check whether calling redo will mutate storage
|
|
1830
|
+
*/
|
|
1831
|
+
const canRedo: boolean = useCanRedo();
|
|
1824
1832
|
|
|
1825
|
-
|
|
1833
|
+
const [messages, sharedType] = useStorage("messages");
|
|
1826
1834
|
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
+
/**
|
|
1836
|
+
* @description Calling transact will enable a storage mutation to be undone/redone.
|
|
1837
|
+
* When called without an origin, the origin will default to the user's connection
|
|
1838
|
+
* id.
|
|
1839
|
+
*
|
|
1840
|
+
* You can specify a 2nd parameter to transact with a different transaction origin.
|
|
1841
|
+
*/
|
|
1842
|
+
const transact = useTransact();
|
|
1835
1843
|
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1844
|
+
transact(() => {
|
|
1845
|
+
sharedType.push(["hello world!"]);
|
|
1846
|
+
});
|
|
1839
1847
|
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1848
|
+
// This will also be undoable because `"user-123"` is a tracked origin.
|
|
1849
|
+
transact(() => {
|
|
1850
|
+
sharedType.push(["hello world!"]);
|
|
1851
|
+
}, "user-123");
|
|
1844
1852
|
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1853
|
+
/**
|
|
1854
|
+
* @description Undoes the last valid mutation to storage
|
|
1855
|
+
*/
|
|
1856
|
+
const undo = useUndo();
|
|
1849
1857
|
|
|
1850
|
-
|
|
1858
|
+
undo();
|
|
1851
1859
|
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1860
|
+
/**
|
|
1861
|
+
* @description Re-applies the last undone mutation to storage
|
|
1862
|
+
*/
|
|
1863
|
+
const redo = useRedo();
|
|
1856
1864
|
|
|
1857
|
-
|
|
1858
|
-
|
|
1865
|
+
redo();
|
|
1866
|
+
```
|
|
1859
1867
|
|
|
1860
1868
|
### Patch Changes
|
|
1861
1869
|
|
|
1862
1870
|
- Updated dependencies [436040b]
|
|
1863
|
-
|
|
1864
|
-
|
|
1871
|
+
- @pluv/crdt-yjs@0.12.0
|
|
1872
|
+
- @pluv/types@0.12.0
|
|
1865
1873
|
|
|
1866
1874
|
## 0.11.1
|
|
1867
1875
|
|
|
@@ -1869,8 +1877,8 @@
|
|
|
1869
1877
|
|
|
1870
1878
|
- 74b3061: Bumped minor and patch dependencies.
|
|
1871
1879
|
- Updated dependencies [74b3061]
|
|
1872
|
-
|
|
1873
|
-
|
|
1880
|
+
- @pluv/crdt-yjs@0.11.1
|
|
1881
|
+
- @pluv/types@0.11.1
|
|
1874
1882
|
|
|
1875
1883
|
## 0.11.0
|
|
1876
1884
|
|
|
@@ -1899,8 +1907,8 @@
|
|
|
1899
1907
|
|
|
1900
1908
|
- 885835d: remove unnecessary dependency
|
|
1901
1909
|
- Updated dependencies [885835d]
|
|
1902
|
-
|
|
1903
|
-
|
|
1910
|
+
- @pluv/crdt-yjs@0.10.1
|
|
1911
|
+
- @pluv/types@0.10.1
|
|
1904
1912
|
|
|
1905
1913
|
## 0.10.0
|
|
1906
1914
|
|
|
@@ -1911,8 +1919,8 @@
|
|
|
1911
1919
|
### Patch Changes
|
|
1912
1920
|
|
|
1913
1921
|
- Updated dependencies [f43f1cc]
|
|
1914
|
-
|
|
1915
|
-
|
|
1922
|
+
- @pluv/crdt-yjs@0.10.0
|
|
1923
|
+
- @pluv/types@0.10.0
|
|
1916
1924
|
|
|
1917
1925
|
## 0.9.2
|
|
1918
1926
|
|
|
@@ -1920,21 +1928,21 @@
|
|
|
1920
1928
|
|
|
1921
1929
|
- f4317ba: \* Renamed type `unstable_YObjectValue` to `YObjectValue`;
|
|
1922
1930
|
|
|
1923
|
-
|
|
1924
|
-
|
|
1931
|
+
- Renamed type `unstable_YObject` to `YObject`.
|
|
1932
|
+
- Re-exported `xmlElement`, `xmlFragment` and `xmlText` from `@pluv/client`.
|
|
1925
1933
|
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1934
|
+
```ts
|
|
1935
|
+
import { y } from "@pluv/client";
|
|
1936
|
+
// or
|
|
1937
|
+
import { y } from "@pluv/react";
|
|
1930
1938
|
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1939
|
+
y.xmlElement("MyElement", {});
|
|
1940
|
+
y.xmlFragment({});
|
|
1941
|
+
y.xmlText("hello world");
|
|
1942
|
+
```
|
|
1935
1943
|
|
|
1936
1944
|
- Updated dependencies [f4317ba]
|
|
1937
|
-
|
|
1945
|
+
- @pluv/crdt-yjs@0.4.2
|
|
1938
1946
|
|
|
1939
1947
|
## 0.9.1
|
|
1940
1948
|
|
|
@@ -1944,8 +1952,8 @@
|
|
|
1944
1952
|
- 8997c65: bumped dependencies
|
|
1945
1953
|
- Updated dependencies [8fba48b]
|
|
1946
1954
|
- Updated dependencies [8997c65]
|
|
1947
|
-
|
|
1948
|
-
|
|
1955
|
+
- @pluv/crdt-yjs@0.4.1
|
|
1956
|
+
- @pluv/types@0.2.2
|
|
1949
1957
|
|
|
1950
1958
|
## 0.9.0
|
|
1951
1959
|
|
|
@@ -1953,49 +1961,49 @@
|
|
|
1953
1961
|
|
|
1954
1962
|
- 829d31b: Added support for defining persistant frontend storage for rooms via a new `addons` option on rooms.
|
|
1955
1963
|
|
|
1956
|
-
|
|
1964
|
+
This also introduces the first new addon `@pluv/addon-indexeddb`, which is more-or-less the equivalent to `y-indexeddb` which you can install like so:
|
|
1957
1965
|
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1966
|
+
```
|
|
1967
|
+
npm install @pluv/addon-indexeddb
|
|
1968
|
+
```
|
|
1961
1969
|
|
|
1962
|
-
|
|
1970
|
+
To use this new addon, simply pass it to options when creating a room:
|
|
1963
1971
|
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1972
|
+
```ts
|
|
1973
|
+
import { addonIndexedDB } from "@pluv/addon-indexeddb";
|
|
1974
|
+
import { createClient } from "@pluv/client";
|
|
1967
1975
|
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1976
|
+
const client = createClient({
|
|
1977
|
+
// ...
|
|
1978
|
+
});
|
|
1971
1979
|
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1980
|
+
const room = client.createRoom("my-new-room", {
|
|
1981
|
+
addons: [
|
|
1982
|
+
// Define your addons in an array like so
|
|
1983
|
+
addonIndexedDB(),
|
|
1984
|
+
],
|
|
1985
|
+
});
|
|
1986
|
+
```
|
|
1979
1987
|
|
|
1980
|
-
|
|
1988
|
+
Or when using `@pluv/react`:
|
|
1981
1989
|
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1990
|
+
```ts
|
|
1991
|
+
const PluvRoom = createRoomBundle({
|
|
1992
|
+
// ...
|
|
1993
|
+
addons: [
|
|
1994
|
+
// Define your addons in an array like so
|
|
1995
|
+
addonIndexedDB(),
|
|
1996
|
+
],
|
|
1997
|
+
});
|
|
1998
|
+
```
|
|
1991
1999
|
|
|
1992
2000
|
### Patch Changes
|
|
1993
2001
|
|
|
1994
2002
|
- 8d11672: bumped dependencies to latest
|
|
1995
2003
|
- Updated dependencies [8d11672]
|
|
1996
2004
|
- Updated dependencies [829d31b]
|
|
1997
|
-
|
|
1998
|
-
|
|
2005
|
+
- @pluv/crdt-yjs@0.4.0
|
|
2006
|
+
- @pluv/types@0.2.1
|
|
1999
2007
|
|
|
2000
2008
|
## 0.8.1
|
|
2001
2009
|
|
|
@@ -2014,8 +2022,8 @@
|
|
|
2014
2022
|
- 5bbfb98: fix not properly handling unauthorized checks
|
|
2015
2023
|
- b85a232: bumped dependencies
|
|
2016
2024
|
- Updated dependencies [b85a232]
|
|
2017
|
-
|
|
2018
|
-
|
|
2025
|
+
- @pluv/crdt-yjs@0.3.8
|
|
2026
|
+
- @pluv/types@0.2.0
|
|
2019
2027
|
|
|
2020
2028
|
## 0.7.0
|
|
2021
2029
|
|
|
@@ -2032,8 +2040,8 @@
|
|
|
2032
2040
|
- Updated dependencies [bb2886b]
|
|
2033
2041
|
- Updated dependencies [ae679a8]
|
|
2034
2042
|
- Updated dependencies [3518a83]
|
|
2035
|
-
|
|
2036
|
-
|
|
2043
|
+
- @pluv/crdt-yjs@0.3.7
|
|
2044
|
+
- @pluv/types@0.2.0
|
|
2037
2045
|
|
|
2038
2046
|
## 0.6.5
|
|
2039
2047
|
|
|
@@ -2041,8 +2049,8 @@
|
|
|
2041
2049
|
|
|
2042
2050
|
- 7ad4967: fixed user's presence not updating locally while offline
|
|
2043
2051
|
- 4535687: fix local yjs doc not updating while disconnected
|
|
2044
|
-
|
|
2045
|
-
|
|
2052
|
+
- @pluv/crdt-yjs@0.3.6
|
|
2053
|
+
- @pluv/types@0.1.6
|
|
2046
2054
|
|
|
2047
2055
|
## 0.6.4
|
|
2048
2056
|
|
|
@@ -2050,7 +2058,7 @@
|
|
|
2050
2058
|
|
|
2051
2059
|
- 78fd644: updated readmes with links to the documentation website
|
|
2052
2060
|
- Updated dependencies [78fd644]
|
|
2053
|
-
|
|
2061
|
+
- @pluv/crdt-yjs@0.3.6
|
|
2054
2062
|
|
|
2055
2063
|
## 0.6.3
|
|
2056
2064
|
|
|
@@ -2058,8 +2066,8 @@
|
|
|
2058
2066
|
|
|
2059
2067
|
- 850626e: bumped dependencies
|
|
2060
2068
|
- Updated dependencies [850626e]
|
|
2061
|
-
|
|
2062
|
-
|
|
2069
|
+
- @pluv/crdt-yjs@0.3.5
|
|
2070
|
+
- @pluv/types@0.1.6
|
|
2063
2071
|
|
|
2064
2072
|
## 0.6.2
|
|
2065
2073
|
|
|
@@ -2067,7 +2075,7 @@
|
|
|
2067
2075
|
|
|
2068
2076
|
- 9ae251d: bumped dependencies
|
|
2069
2077
|
- Updated dependencies [9ae251d]
|
|
2070
|
-
|
|
2078
|
+
- @pluv/crdt-yjs@0.3.4
|
|
2071
2079
|
|
|
2072
2080
|
## 0.6.1
|
|
2073
2081
|
|
|
@@ -2076,8 +2084,8 @@
|
|
|
2076
2084
|
- 19433af: updated MockedRoomProvider events to allow partial events
|
|
2077
2085
|
- 74870ee: bumped dependencies
|
|
2078
2086
|
- Updated dependencies [74870ee]
|
|
2079
|
-
|
|
2080
|
-
|
|
2087
|
+
- @pluv/crdt-yjs@0.3.3
|
|
2088
|
+
- @pluv/types@0.1.5
|
|
2081
2089
|
|
|
2082
2090
|
## 0.6.0
|
|
2083
2091
|
|
|
@@ -2096,8 +2104,8 @@
|
|
|
2096
2104
|
- Updated dependencies [7b6da1c]
|
|
2097
2105
|
- Updated dependencies [e9c1514]
|
|
2098
2106
|
- Updated dependencies [9d1829c]
|
|
2099
|
-
|
|
2100
|
-
|
|
2107
|
+
- @pluv/crdt-yjs@0.3.2
|
|
2108
|
+
- @pluv/types@0.1.4
|
|
2101
2109
|
|
|
2102
2110
|
## 0.5.1
|
|
2103
2111
|
|
|
@@ -2107,8 +2115,8 @@
|
|
|
2107
2115
|
- f6c0e65: bumped dependencies
|
|
2108
2116
|
- Updated dependencies [161e00e]
|
|
2109
2117
|
- Updated dependencies [f6c0e65]
|
|
2110
|
-
|
|
2111
|
-
|
|
2118
|
+
- @pluv/crdt-yjs@0.3.1
|
|
2119
|
+
- @pluv/types@0.1.3
|
|
2112
2120
|
|
|
2113
2121
|
## 0.5.0
|
|
2114
2122
|
|
|
@@ -2128,8 +2136,8 @@
|
|
|
2128
2136
|
- Updated dependencies [b1cb325]
|
|
2129
2137
|
- Updated dependencies [327a6ef]
|
|
2130
2138
|
- Updated dependencies [8e97fb2]
|
|
2131
|
-
|
|
2132
|
-
|
|
2139
|
+
- @pluv/crdt-yjs@0.3.0
|
|
2140
|
+
- @pluv/types@0.1.3
|
|
2133
2141
|
|
|
2134
2142
|
## 0.4.0
|
|
2135
2143
|
|
|
@@ -2152,8 +2160,8 @@
|
|
|
2152
2160
|
### Patch Changes
|
|
2153
2161
|
|
|
2154
2162
|
- Updated dependencies [6858682]
|
|
2155
|
-
|
|
2156
|
-
|
|
2163
|
+
- @pluv/crdt-yjs@0.2.0
|
|
2164
|
+
- @pluv/types@0.1.2
|
|
2157
2165
|
|
|
2158
2166
|
## 0.1.3
|
|
2159
2167
|
|
|
@@ -2161,15 +2169,15 @@
|
|
|
2161
2169
|
|
|
2162
2170
|
- fe80d7b: added preview disclaimer about breaking changes in the readme
|
|
2163
2171
|
- Updated dependencies [fe80d7b]
|
|
2164
|
-
|
|
2165
|
-
|
|
2172
|
+
- @pluv/crdt-yjs@0.1.3
|
|
2173
|
+
- @pluv/types@0.1.2
|
|
2166
2174
|
|
|
2167
2175
|
## 0.1.2
|
|
2168
2176
|
|
|
2169
2177
|
### Patch Changes
|
|
2170
2178
|
|
|
2171
2179
|
- Updated dependencies [b45d642]
|
|
2172
|
-
|
|
2180
|
+
- @pluv/crdt-yjs@0.1.2
|
|
2173
2181
|
|
|
2174
2182
|
## 0.1.1
|
|
2175
2183
|
|
|
@@ -2178,8 +2186,8 @@
|
|
|
2178
2186
|
- 23a7382: Omitted unused `encodedState` param from PluvRoom.
|
|
2179
2187
|
- 24016e6: Updated dependencies
|
|
2180
2188
|
- Updated dependencies [24016e6]
|
|
2181
|
-
|
|
2182
|
-
|
|
2189
|
+
- @pluv/crdt-yjs@0.1.1
|
|
2190
|
+
- @pluv/types@0.1.1
|
|
2183
2191
|
|
|
2184
2192
|
## 0.1.0
|
|
2185
2193
|
|
|
@@ -2190,5 +2198,5 @@
|
|
|
2190
2198
|
### Patch Changes
|
|
2191
2199
|
|
|
2192
2200
|
- Updated dependencies [a22f525]
|
|
2193
|
-
|
|
2194
|
-
|
|
2201
|
+
- @pluv/crdt-yjs@0.1.0
|
|
2202
|
+
- @pluv/types@0.1.0
|