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