@pluv/io 0.14.1 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,18 +1,18 @@
1
1
 
2
- > @pluv/io@0.14.1 build /home/runner/work/pluv/pluv/packages/io
2
+ > @pluv/io@0.16.0 build /home/runner/work/pluv/pluv/packages/io
3
3
  > tsup src/index.ts --format esm,cjs --dts
4
4
 
5
5
  CLI Building entry: src/index.ts
6
6
  CLI Using tsconfig: tsconfig.json
7
- CLI tsup v8.0.1
7
+ CLI tsup v8.0.2
8
8
  CLI Target: es6
9
9
  ESM Build start
10
10
  CJS Build start
11
- ESM dist/index.mjs 29.30 KB
12
- ESM ⚡️ Build success in 65ms
13
- CJS dist/index.js 31.38 KB
14
- CJS ⚡️ Build success in 69ms
11
+ ESM dist/index.mjs 29.59 KB
12
+ ESM ⚡️ Build success in 139ms
13
+ CJS dist/index.js 31.65 KB
14
+ CJS ⚡️ Build success in 141ms
15
15
  DTS Build start
16
- DTS ⚡️ Build success in 2232ms
17
- DTS dist/index.d.mts 17.23 KB
18
- DTS dist/index.d.ts 17.23 KB
16
+ DTS ⚡️ Build success in 3210ms
17
+ DTS dist/index.d.mts 17.61 KB
18
+ DTS dist/index.d.ts 17.61 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,163 @@
1
1
  # @pluv/io
2
2
 
3
+ ## 0.16.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 4280220: ## Breaking Changes
8
+
9
+ - Storage types are now kept on the root of the document.
10
+ - 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.
11
+ - `@pluv/client` and `@pluv/react` no-longer re-export `@pluv/crdt-yjs`. This package will now need to be installed separately.
12
+
13
+ ```bash
14
+ # if installing @pluv/client
15
+ npm install @pluv/client @pluv/crdt-yjs
16
+ # if installing @pluv/react
17
+ npm install @pluv/react @pluv/crdt-yjs
18
+ ```
19
+
20
+ ```ts
21
+ // Before:
22
+ import { createClient, y } from "@pluv/client";
23
+ // After:
24
+ import { createClient } from "@pluv/client";
25
+ import { yjs } from "@pluv/crdt-yjs"; // y renamed to yjs
26
+ ```
27
+
28
+ - The `y` import has been renamed to `yjs`.
29
+ ```ts
30
+ // Before:
31
+ import { y } from "@pluv/crdt-yjs";
32
+ // After:
33
+ import { yjs } from "@pluv/crdt-yjs";
34
+ ```
35
+ - `@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`.
36
+
37
+ ```ts
38
+ // Before:
39
+ import { y } from "@pluv/crdt-yjs";
40
+ import type { Array as YArray, Map as YMap } from "yjs";
41
+
42
+ const array: YArray<YMap<{ message: string }>> = y.array([
43
+ y.object({ message: "Hello" }),
44
+ ]);
45
+
46
+ array.push([y.object({ message: "World!" })]);
47
+
48
+ // After:
49
+ import type { CrdtYjsArray, CrdtYjsObject } from "@pluv/crdt-yjs";
50
+ import { yjs } from "@pluv/crdt-yjs";
51
+ import type { Array as YArray } from "yjs";
52
+
53
+ const array: CrdtYjsArray<CrdtYjsObject<{ message: string }>> = yjs.array([
54
+ yjs.object({ message: "Hello" }),
55
+ ]);
56
+
57
+ array.push(yjs.object({ message: "World!" }));
58
+
59
+ // use .value to get the underlying yjs type
60
+ const yarray: YArray<YMap<{ message: string }>> = array.value;
61
+ ```
62
+
63
+ - `initialStorage` must now use the `doc` function from `@pluv/crdt-yjs` to be defined. This also affects `@pluv/react`.
64
+
65
+ ```ts
66
+ // Before:
67
+ import { createClient, y } from "@pluv/client";
68
+
69
+ const client = createClient({
70
+ /* ... */
71
+ });
72
+
73
+ client.createRoom({
74
+ // ...
75
+ initialStorage: () => ({
76
+ messages: y.array([y.object({ message: "Hello world!" })]),
77
+ }),
78
+ });
79
+
80
+ // After:
81
+ import { createClient } from "@pluv/client";
82
+ // This is now imported separately
83
+ import { yjs } from "@pluv/crdt-yjs";
84
+
85
+ const client = createClient({
86
+ /* ... */
87
+ });
88
+
89
+ client.createRoom({
90
+ // ...
91
+ initialStorage: yjs.doc(() => ({
92
+ messages: yjs.array([yjs.object({ message: "Hello world!" })]),
93
+ })),
94
+ });
95
+ ```
96
+
97
+ - `@pluv/client` can now instead use [loro](https://github.com/loro-dev/loro) instead of [yjs](https://github.com/yjs/yjs).
98
+ ```bash
99
+ npm install @pluv/client @pluv/crdt-loro loro-crdt
100
+ ```
101
+ - 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.
102
+
103
+ ```ts
104
+ import { loro } from "@pluv/crdt-loro";
105
+ import { yjs } from "@pluv/crdt-yjs";
106
+ import { createIO } from "@pluv/io";
107
+
108
+ const io = createIO({
109
+ // ...
110
+ // If using loro
111
+ crdt: loro,
112
+ // If using yjs
113
+ crdt: yjs,
114
+ });
115
+ ```
116
+
117
+ - `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`.
118
+
119
+ ```ts
120
+ // Before:
121
+ import { Doc as YDoc } from "yjs";
122
+
123
+ const room: PluvRoom = client.createRoom({
124
+ /* ... */
125
+ });
126
+
127
+ const doc: YDoc = room.getDoc();
128
+
129
+ // After:
130
+ import { CrdtYjsDoc } from "@pluv/crdt-yjs";
131
+ import { Doc as YDoc } from "yjs";
132
+
133
+ const room: PluvRoom = client.createRoom({
134
+ /* ... */
135
+ });
136
+
137
+ const doc: CrdtYjsDoc<any> = room.getDoc();
138
+ const ydoc: YDoc = doc.value;
139
+ ```
140
+
141
+ - `@pluv/client` and `@pluv/react` now may return `null` when retrieving storage while storage is being initialized.
142
+
143
+ ```ts
144
+ const sharedType = room.getStorage("messages"); // This may be null
145
+
146
+ const [data, sharedType] = useStorage("messages"); // data and sharedType may both be null
147
+ ```
148
+
149
+ ### Patch Changes
150
+
151
+ - @pluv/crdt@0.16.0
152
+ - @pluv/types@0.16.0
153
+
154
+ ## 0.15.0
155
+
156
+ ### Patch Changes
157
+
158
+ - @pluv/crdt-yjs@0.15.0
159
+ - @pluv/types@0.15.0
160
+
3
161
  ## 0.14.1
4
162
 
5
163
  ### Patch Changes
package/README.md CHANGED
@@ -5,12 +5,12 @@
5
5
  <br />
6
6
  <img src="https://github.com/pluv-io/pluv/blob/master/assets/pluv-icon-192x192.png?raw=true" alt="Pluv.IO" width="180" style="border-radius:16px" />
7
7
  <br />
8
- Pluv.IO (preview)
8
+ <a href="https://pluv.io/docs/introduction">Pluv.IO (preview)</a>
9
9
  <br />
10
10
  </h1>
11
11
 
12
12
  <h3 align="center">Multi-platform, E2E type-safe realtime packages</h3>
13
- <h4 align="center">💕 Inspired by <a href="https://trpc.io">trpc</a> 💕 Built with <a href="https://docs.yjs.dev/">yjs</a> 💕</h4>
13
+ <h4 align="center">💕 Inspired by <a href="https://trpc.io">trpc</a> 💕 <a href="https://docs.yjs.dev/">yjs</a> 💕 and <a href="https://developers.cloudflare.com/">Cloudflare</a> 💕 </h4>
14
14
 
15
15
  <p align="center">
16
16
  <a href="https://www.npmjs.com/package/@pluv/io">
@@ -22,13 +22,7 @@
22
22
  <a href="https://commitizen.github.io/cz-cli/">
23
23
  <img src="https://img.shields.io/badge/commitizen-friendly-brightgreen.svg" alt="Commitizen friendly" />
24
24
  </a>
25
- </p>
26
-
27
- <p align="center">
28
25
  <img src="https://badgen.net/badge/-/TypeScript?icon=typescript&label&labelColor=blue&color=555555" alt="TypeScript" />
29
- <a href="https://openbase.com/js/@pluv/io?utm_source=embedded&amp;utm_medium=badge&amp;utm_campaign=rate-badge">
30
- <img src="https://badges.openbase.com/js/featured/@pluv/io.svg?token=FdWfpo90mCUb7InAjDG0KeXM/uH+KdHK3us2pNRgWf0=" alt="Featured on Openbase" />
31
- </a>
32
26
  </p>
33
27
 
34
28
  <p align="center">
@@ -39,32 +33,12 @@
39
33
  <a href="#license">License</a>
40
34
  </p>
41
35
 
42
- <p align="center">
43
- <img src="https://github.com/pluv-io/pluv/blob/master/assets/demo-events.gif?raw=true" alt="Demo" />
44
- </p>
45
-
46
36
  ## Intro
47
37
 
48
- Pluv.IO allows you to build real-time collaborative features with a fully end-to-end type-safe api.
38
+ pluv.io allows you to more easily build real-time collaborative experiences with a fully end-to-end type-safe api and the ecosystem of existing CRDT implementations such as **[yjs](https://docs.yjs.dev/)**.
49
39
 
50
40
  **👉 See full documentation on [pluv.io](https://pluv.io/docs/introduction). 👈**
51
41
 
52
- ### Why?
53
-
54
- So you can do this:
55
-
56
- ```tsx
57
- const broadcast = usePluvBroadcast();
58
-
59
- usePluvEvent("RECEIVE_MESSAGE", ({ data }) => {
60
- setMessages([...messages, data.message]);
61
- });
62
-
63
- broadcast("SEND_MESSAGE", { message: "Hello world!" });
64
- ```
65
-
66
- And more. With **E2E type-safety**, **great intellisense** and the **[yjs](https://docs.yjs.dev/) ecosystem**.
67
-
68
42
  ### Features
69
43
 
70
44
  - ✅ Automatic type safety
@@ -72,14 +46,21 @@ And more. With **E2E type-safety**, **great intellisense** and the **[yjs](https
72
46
  - ✅ Rooms
73
47
  - ✅ Authentication
74
48
  - ✅ Awareness + Presence
75
- - ✅ [CRDTs](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type) (with [Yjs](https://docs.yjs.dev/))
76
- - ✅ **Shared Types**
77
- - ✅ [Map](https://docs.yjs.dev/api/shared-types/y.map)
78
- - ✅ [Array](https://docs.yjs.dev/api/shared-types/y.array)
79
- - ✅ [Text](https://docs.yjs.dev/api/shared-types/y.text)
80
- - ✅ [XmlFragment](https://docs.yjs.dev/api/shared-types/y.xmlfragment)
81
- - ✅ [XmlElement](https://docs.yjs.dev/api/shared-types/y.xmlelement)
82
- - ✅ [XmlText](https://docs.yjs.dev/api/shared-types/y.xmltext)
49
+ - ✅ [CRDTs](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type)
50
+ - ✅ [Yjs](https://docs.yjs.dev/)
51
+ - ✅ **Shared Types**
52
+ - ✅ [Map](https://docs.yjs.dev/api/shared-types/y.map)
53
+ - ✅ [Array](https://docs.yjs.dev/api/shared-types/y.array)
54
+ - ✅ [Text](https://docs.yjs.dev/api/shared-types/y.text)
55
+ - ✅ [XmlFragment](https://docs.yjs.dev/api/shared-types/y.xmlfragment)
56
+ - ✅ [XmlElement](https://docs.yjs.dev/api/shared-types/y.xmlelement)
57
+ - ✅ [XmlText](https://docs.yjs.dev/api/shared-types/y.xmltext)
58
+ - ✅ [Loro](https://loro.dev/)
59
+ - ✅ **Containers**
60
+ - ✅ List
61
+ - ✅ Map
62
+ - ✅ Text
63
+ - ⬜ Tree
83
64
  - ⬜ Studio (admin & developer panel)
84
65
 
85
66
  ### Runtimes
@@ -96,7 +77,8 @@ And more. With **E2E type-safety**, **great intellisense** and the **[yjs](https
96
77
 
97
78
  ### Frontends
98
79
 
99
- - ✅ [React.js](https://beta.reactjs.org/)
80
+ - ✅ [React.js](https://react.dev/)
81
+ - ⬜ [Solid.js](https://www.solidjs.com/)
100
82
  - ⬜ [Vue.js](https://vuejs.org/)
101
83
  - ⬜ [Svelte](https://svelte.dev/)
102
84
 
@@ -114,7 +96,8 @@ Documentation is available at [pluv.io](https://pluv.io/docs/introduction).
114
96
  ## Related
115
97
 
116
98
  - [@pluv/client](https://www.npmjs.com/package/@pluv/client) - Framework agnostic client
117
- - [@pluv/crdt-yjs](https://www.npmjs.com/package/@pluv/crdt-yjs) - Yjs for Pluv.IO
99
+ - [@pluv/crdt-loro](https://www.npmjs.com/package/@pluv/crdt-loro) - Loro CRDT for Pluv.IO
100
+ - [@pluv/crdt-yjs](https://www.npmjs.com/package/@pluv/crdt-yjs) - Yjs CRDT for Pluv.IO
118
101
  - [@pluv/persistance-redis](https://www.npmjs.com/package/@pluv/persistance-redis) - Persistance for storage on distributed systems (Node.js only)
119
102
  - [@pluv/platform-cloudflare](https://www.npmjs.com/package/@pluv/platform-cloudflare) - Adapter to run @pluv/io on Cloudflare Workers
120
103
  - [@pluv/platform-node](https://www.npmjs.com/package/@pluv/platform-node) - Adapter to run @pluv/io on Node.js
@@ -125,6 +108,7 @@ Documentation is available at [pluv.io](https://pluv.io/docs/introduction).
125
108
 
126
109
  This software uses the following open source tooling and libraries:
127
110
 
111
+ - [Loro](https://loro.dev/)
128
112
  - [Yjs](https://yjs.dev/)
129
113
  - [Node.js](https://nodejs.org/)
130
114
  - [Cloudflare Workers](https://workers.cloudflare.com/)
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { JsonObject, MaybePromise, IOEventMessage, EventRecord, InputZodLike, Id, IOLike, InferIOOutput, IOAuthorize, BaseIOAuthorize, InferIOInput, BaseUser, InferIOAuthorizeUser, InferIOAuthorize, Spread, InferIOOutputBroadcast, InferIOOutputSelf, InferIOOutputSync, Maybe, BaseClientEventRecord, BaseIOEventRecord } from '@pluv/types';
2
2
  export { BaseUser, EventMessage, EventRecord, IOEventMessage } from '@pluv/types';
3
- import { YjsDoc } from '@pluv/crdt-yjs';
3
+ import { AbstractCrdtDoc, AbstractCrdtDocFactory } from '@pluv/crdt';
4
4
 
5
5
  declare abstract class AbstractPersistance {
6
6
  abstract addUser(room: string, connectionId: string, user: JsonObject | null): Promise<void>;
@@ -88,7 +88,7 @@ type SyncEventResolver<TContext extends Record<string, any> = {}, TData extends
88
88
  type EventResolver<TContext extends Record<string, any> = {}, TData extends JsonObject = {}, TResultBroadcast extends EventRecord<string, any> = {}> = (data: TData, context: EventResolverContext<TContext>) => MaybePromise<TResultBroadcast | void>;
89
89
  interface EventResolverContext<TContext extends Record<string, any> = {}> {
90
90
  context: TContext;
91
- doc: YjsDoc<any>;
91
+ doc: AbstractCrdtDoc<any>;
92
92
  room: string;
93
93
  /**
94
94
  * !HACK
@@ -175,6 +175,9 @@ interface IORoomListeners<TPlatform extends AbstractPlatform> {
175
175
  type IORoomConfig<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any> = BaseIOAuthorize, TContext extends JsonObject = {}, TInput extends EventRecord<string, any> = {}, TOutputBroadcast extends EventRecord<string, any> = {}, TOutputSelf extends EventRecord<string, any> = {}, TOutputSync extends EventRecord<string, any> = {}> = Partial<IORoomListeners<TPlatform>> & {
176
176
  authorize?: TAuthorize;
177
177
  context: TContext & InferPlatformRoomContextType<TPlatform>;
178
+ crdt?: {
179
+ doc: (value: any) => AbstractCrdtDocFactory<any>;
180
+ };
178
181
  debug: boolean;
179
182
  events: InferEventConfig<TPlatform, TContext, TInput, TOutputBroadcast, TOutputSelf, TOutputSync>;
180
183
  platform: TPlatform;
@@ -185,6 +188,7 @@ type WebsocketRegisterOptions<TPlatform extends AbstractPlatform> = {
185
188
  declare class IORoom<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any> = BaseIOAuthorize, TContext extends Record<string, any> = {}, TInput extends EventRecord<string, any> = {}, TOutputBroadcast extends EventRecord<string, any> = {}, TOutputSelf extends EventRecord<string, any> = {}, TOutputSync extends EventRecord<string, any> = {}> implements IOLike<TAuthorize, TInput, TOutputBroadcast, TOutputSelf, TOutputSync> {
186
189
  private readonly _context;
187
190
  private readonly _debug;
191
+ private readonly _docFactory;
188
192
  private readonly _platform;
189
193
  private _doc;
190
194
  private _listeners;
@@ -248,6 +252,9 @@ interface PluvIOListeners<TPlatform extends AbstractPlatform> {
248
252
  type PluvIOConfig<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any> | null = null, TContext extends JsonObject = {}, TInput extends EventRecord<string, any> = {}, TOutputBroadcast extends EventRecord<string, any> = {}, TOutputSelf extends EventRecord<string, any> = {}, TOutputSync extends EventRecord<string, any> = {}> = Partial<PluvIOListeners<TPlatform>> & {
249
253
  authorize?: TAuthorize;
250
254
  context?: TContext;
255
+ crdt?: {
256
+ doc: (value: any) => AbstractCrdtDocFactory<any>;
257
+ };
251
258
  debug?: boolean;
252
259
  events?: InferEventConfig<TPlatform, TContext, TInput, TOutputBroadcast, TOutputSelf, TOutputSync>;
253
260
  getInitialStorage?: GetInitialStorageFn<TPlatform>;
@@ -260,6 +267,9 @@ declare class PluvIO<TPlatform extends AbstractPlatform<any> = AbstractPlatform<
260
267
  private _rooms;
261
268
  readonly _authorize: TAuthorize | null;
262
269
  readonly _context: TContext;
270
+ readonly _crdt: {
271
+ doc: (value: any) => AbstractCrdtDocFactory<any>;
272
+ };
263
273
  readonly _debug: boolean;
264
274
  readonly _events: InferEventConfig<TPlatform, TContext, TInput, TOutputBroadcast, TOutputSelf, TOutputSync>;
265
275
  readonly _getInitialStorage: GetInitialStorageFn<TPlatform> | null;
@@ -277,6 +287,9 @@ declare class PluvIO<TPlatform extends AbstractPlatform<any> = AbstractPlatform<
277
287
  type CreateIOParams<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TContext extends JsonObject = {}, TAuthorizeUser extends BaseUser = BaseUser, TAuthorizeRequired extends boolean = false> = Partial<PluvIOListeners<TPlatform>> & {
278
288
  authorize?: IOAuthorize<TAuthorizeUser, TAuthorizeRequired>;
279
289
  context?: TContext;
290
+ crdt?: {
291
+ doc: (value: any) => AbstractCrdtDocFactory<any>;
292
+ };
280
293
  debug?: boolean;
281
294
  getInitialStorage?: GetInitialStorageFn<TPlatform>;
282
295
  platform: TPlatform;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { JsonObject, MaybePromise, IOEventMessage, EventRecord, InputZodLike, Id, IOLike, InferIOOutput, IOAuthorize, BaseIOAuthorize, InferIOInput, BaseUser, InferIOAuthorizeUser, InferIOAuthorize, Spread, InferIOOutputBroadcast, InferIOOutputSelf, InferIOOutputSync, Maybe, BaseClientEventRecord, BaseIOEventRecord } from '@pluv/types';
2
2
  export { BaseUser, EventMessage, EventRecord, IOEventMessage } from '@pluv/types';
3
- import { YjsDoc } from '@pluv/crdt-yjs';
3
+ import { AbstractCrdtDoc, AbstractCrdtDocFactory } from '@pluv/crdt';
4
4
 
5
5
  declare abstract class AbstractPersistance {
6
6
  abstract addUser(room: string, connectionId: string, user: JsonObject | null): Promise<void>;
@@ -88,7 +88,7 @@ type SyncEventResolver<TContext extends Record<string, any> = {}, TData extends
88
88
  type EventResolver<TContext extends Record<string, any> = {}, TData extends JsonObject = {}, TResultBroadcast extends EventRecord<string, any> = {}> = (data: TData, context: EventResolverContext<TContext>) => MaybePromise<TResultBroadcast | void>;
89
89
  interface EventResolverContext<TContext extends Record<string, any> = {}> {
90
90
  context: TContext;
91
- doc: YjsDoc<any>;
91
+ doc: AbstractCrdtDoc<any>;
92
92
  room: string;
93
93
  /**
94
94
  * !HACK
@@ -175,6 +175,9 @@ interface IORoomListeners<TPlatform extends AbstractPlatform> {
175
175
  type IORoomConfig<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any> = BaseIOAuthorize, TContext extends JsonObject = {}, TInput extends EventRecord<string, any> = {}, TOutputBroadcast extends EventRecord<string, any> = {}, TOutputSelf extends EventRecord<string, any> = {}, TOutputSync extends EventRecord<string, any> = {}> = Partial<IORoomListeners<TPlatform>> & {
176
176
  authorize?: TAuthorize;
177
177
  context: TContext & InferPlatformRoomContextType<TPlatform>;
178
+ crdt?: {
179
+ doc: (value: any) => AbstractCrdtDocFactory<any>;
180
+ };
178
181
  debug: boolean;
179
182
  events: InferEventConfig<TPlatform, TContext, TInput, TOutputBroadcast, TOutputSelf, TOutputSync>;
180
183
  platform: TPlatform;
@@ -185,6 +188,7 @@ type WebsocketRegisterOptions<TPlatform extends AbstractPlatform> = {
185
188
  declare class IORoom<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any> = BaseIOAuthorize, TContext extends Record<string, any> = {}, TInput extends EventRecord<string, any> = {}, TOutputBroadcast extends EventRecord<string, any> = {}, TOutputSelf extends EventRecord<string, any> = {}, TOutputSync extends EventRecord<string, any> = {}> implements IOLike<TAuthorize, TInput, TOutputBroadcast, TOutputSelf, TOutputSync> {
186
189
  private readonly _context;
187
190
  private readonly _debug;
191
+ private readonly _docFactory;
188
192
  private readonly _platform;
189
193
  private _doc;
190
194
  private _listeners;
@@ -248,6 +252,9 @@ interface PluvIOListeners<TPlatform extends AbstractPlatform> {
248
252
  type PluvIOConfig<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any> | null = null, TContext extends JsonObject = {}, TInput extends EventRecord<string, any> = {}, TOutputBroadcast extends EventRecord<string, any> = {}, TOutputSelf extends EventRecord<string, any> = {}, TOutputSync extends EventRecord<string, any> = {}> = Partial<PluvIOListeners<TPlatform>> & {
249
253
  authorize?: TAuthorize;
250
254
  context?: TContext;
255
+ crdt?: {
256
+ doc: (value: any) => AbstractCrdtDocFactory<any>;
257
+ };
251
258
  debug?: boolean;
252
259
  events?: InferEventConfig<TPlatform, TContext, TInput, TOutputBroadcast, TOutputSelf, TOutputSync>;
253
260
  getInitialStorage?: GetInitialStorageFn<TPlatform>;
@@ -260,6 +267,9 @@ declare class PluvIO<TPlatform extends AbstractPlatform<any> = AbstractPlatform<
260
267
  private _rooms;
261
268
  readonly _authorize: TAuthorize | null;
262
269
  readonly _context: TContext;
270
+ readonly _crdt: {
271
+ doc: (value: any) => AbstractCrdtDocFactory<any>;
272
+ };
263
273
  readonly _debug: boolean;
264
274
  readonly _events: InferEventConfig<TPlatform, TContext, TInput, TOutputBroadcast, TOutputSelf, TOutputSync>;
265
275
  readonly _getInitialStorage: GetInitialStorageFn<TPlatform> | null;
@@ -277,6 +287,9 @@ declare class PluvIO<TPlatform extends AbstractPlatform<any> = AbstractPlatform<
277
287
  type CreateIOParams<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TContext extends JsonObject = {}, TAuthorizeUser extends BaseUser = BaseUser, TAuthorizeRequired extends boolean = false> = Partial<PluvIOListeners<TPlatform>> & {
278
288
  authorize?: IOAuthorize<TAuthorizeUser, TAuthorizeRequired>;
279
289
  context?: TContext;
290
+ crdt?: {
291
+ doc: (value: any) => AbstractCrdtDocFactory<any>;
292
+ };
280
293
  debug?: boolean;
281
294
  getInitialStorage?: GetInitialStorageFn<TPlatform>;
282
295
  platform: TPlatform;
package/dist/index.js CHANGED
@@ -261,10 +261,11 @@ var AbstractWebSocket = class {
261
261
  };
262
262
 
263
263
  // src/PluvIO.ts
264
+ var import_crdt2 = require("@pluv/crdt");
264
265
  var import_kleur2 = __toESM(require("kleur"));
265
266
 
266
267
  // src/IORoom.ts
267
- var import_crdt_yjs = require("@pluv/crdt-yjs");
268
+ var import_crdt = require("@pluv/crdt");
268
269
  var import_kleur = __toESM(require("kleur"));
269
270
 
270
271
  // src/authorize.ts
@@ -307,13 +308,22 @@ var authorize = (params) => {
307
308
  var PING_TIMEOUT_MS = 3e4;
308
309
  var IORoom = class {
309
310
  constructor(id, config) {
310
- this._doc = (0, import_crdt_yjs.doc)();
311
311
  this._sessions = /* @__PURE__ */ new Map();
312
312
  this._uninitialize = null;
313
313
  this._authorize = null;
314
- const { authorize: authorize2, context, debug, events, onDestroy, platform } = config;
314
+ const {
315
+ authorize: authorize2,
316
+ context,
317
+ crdt = import_crdt.noop,
318
+ debug,
319
+ events,
320
+ onDestroy,
321
+ platform
322
+ } = config;
315
323
  this._context = context;
316
324
  this._debug = debug;
325
+ this._docFactory = crdt.doc(() => ({}));
326
+ this._doc = this._docFactory.getEmpty();
317
327
  this._events = events;
318
328
  this._platform = platform;
319
329
  this.id = id;
@@ -516,9 +526,9 @@ var IORoom = class {
516
526
  );
517
527
  this._uninitialize = () => __async(this, null, function* () {
518
528
  this._platform.pubSub.unsubscribe(pubSubId);
519
- const encodedState = this._doc.encodeStateAsUpdate();
529
+ const encodedState = this._doc.getEncodedState();
520
530
  this._doc.destroy();
521
- this._doc = (0, import_crdt_yjs.doc)();
531
+ this._doc = this._docFactory.getEmpty();
522
532
  this._listeners.onDestroy(__spreadProps(__spreadValues({}, this._context), {
523
533
  encodedState,
524
534
  room: this.id
@@ -769,7 +779,7 @@ var PluvIO = class _PluvIO {
769
779
  }
770
780
  };
771
781
  },
772
- self: (_0, _1) => __async(this, [_0, _1], function* ({ update }, { context, doc: doc2, room }) {
782
+ self: (_0, _1) => __async(this, [_0, _1], function* ({ update }, { context, doc, room }) {
773
783
  var _a, _b;
774
784
  const oldState = yield this._platform.persistance.getStorageState(room);
775
785
  const updates = [
@@ -779,7 +789,7 @@ var PluvIO = class _PluvIO {
779
789
  update
780
790
  ];
781
791
  if (updates.some((_update) => !!_update)) {
782
- const encodedState = updates.reduce((_doc, _up) => _doc.applyUpdate(_up), doc2).encodeStateAsUpdate();
792
+ const encodedState = doc.batchApplyEncodedState(updates).getEncodedState();
783
793
  yield this._platform.persistance.setStorageState(
784
794
  room,
785
795
  encodedState
@@ -791,7 +801,7 @@ var PluvIO = class _PluvIO {
791
801
  }
792
802
  const state = (_b = yield this._platform.persistance.getStorageState(
793
803
  room
794
- )) != null ? _b : doc2.encodeStateAsUpdate();
804
+ )) != null ? _b : doc.getEncodedState();
795
805
  return { $STORAGE_RECEIVED: { state } };
796
806
  })
797
807
  }
@@ -820,12 +830,12 @@ var PluvIO = class _PluvIO {
820
830
  }
821
831
  },
822
832
  $UPDATE_STORAGE: {
823
- resolver: ({ origin, update }, { context, doc: doc2, room }) => {
824
- if (origin === "$INITIALIZED" && Object.keys(doc2.toJSON()).length) {
833
+ resolver: ({ origin, update }, { context, doc, room }) => {
834
+ if (origin === "$INITIALIZED" && Object.keys(doc.toJson()).length) {
825
835
  return;
826
836
  }
827
- const updated = doc2.applyUpdate(update);
828
- const encodedState = updated.encodeStateAsUpdate();
837
+ const updated = doc.applyEncodedState({ update });
838
+ const encodedState = updated.getEncodedState();
829
839
  this._platform.persistance.setStorageState(room, encodedState).then(() => {
830
840
  this._listeners.onStorageUpdated(__spreadProps(__spreadValues({}, context), {
831
841
  encodedState,
@@ -840,6 +850,7 @@ var PluvIO = class _PluvIO {
840
850
  const {
841
851
  authorize: authorize2,
842
852
  context,
853
+ crdt = import_crdt2.noop,
843
854
  debug = false,
844
855
  events,
845
856
  getInitialStorage,
@@ -847,6 +858,7 @@ var PluvIO = class _PluvIO {
847
858
  onStorageUpdated,
848
859
  platform
849
860
  } = options;
861
+ this._crdt = crdt;
850
862
  this._debug = debug;
851
863
  this._platform = platform;
852
864
  if (authorize2)
@@ -885,6 +897,7 @@ var PluvIO = class _PluvIO {
885
897
  return _PluvIO.merge(
886
898
  this,
887
899
  new _PluvIO({
900
+ crdt: this._crdt,
888
901
  events: newEvent,
889
902
  platform: this._platform
890
903
  })
@@ -905,6 +918,7 @@ var PluvIO = class _PluvIO {
905
918
  const newRoom = new IORoom(room, {
906
919
  authorize: (_b = this._authorize) != null ? _b : void 0,
907
920
  context: roomContext,
921
+ crdt: this._crdt,
908
922
  debug: debug != null ? debug : this._debug,
909
923
  events: this._events,
910
924
  onDestroy: ({ encodedState, room: room2 }) => {
@@ -943,6 +957,7 @@ var PluvIO = class _PluvIO {
943
957
  var _a;
944
958
  const authorize2 = (_a = first._authorize) != null ? _a : void 0;
945
959
  const context = first._context;
960
+ const crdt = first._crdt;
946
961
  const debug = first._debug;
947
962
  const platform = first._platform;
948
963
  const getInitialStorage = first._getInitialStorage;
@@ -953,6 +968,7 @@ var PluvIO = class _PluvIO {
953
968
  return new _PluvIO({
954
969
  authorize: authorize2,
955
970
  context,
971
+ crdt,
956
972
  debug,
957
973
  events,
958
974
  getInitialStorage,
@@ -979,6 +995,7 @@ var createIO = (params) => {
979
995
  const {
980
996
  authorize: authorize2,
981
997
  context,
998
+ crdt,
982
999
  debug,
983
1000
  getInitialStorage,
984
1001
  onRoomDeleted,
@@ -988,6 +1005,7 @@ var createIO = (params) => {
988
1005
  return new PluvIO({
989
1006
  authorize: authorize2,
990
1007
  context,
1008
+ crdt,
991
1009
  debug,
992
1010
  getInitialStorage,
993
1011
  onRoomDeleted,
package/dist/index.mjs CHANGED
@@ -223,10 +223,11 @@ var AbstractWebSocket = class {
223
223
  };
224
224
 
225
225
  // src/PluvIO.ts
226
+ import { noop as noop2 } from "@pluv/crdt";
226
227
  import colors2 from "kleur";
227
228
 
228
229
  // src/IORoom.ts
229
- import { doc } from "@pluv/crdt-yjs";
230
+ import { noop } from "@pluv/crdt";
230
231
  import colors from "kleur";
231
232
 
232
233
  // src/authorize.ts
@@ -269,13 +270,22 @@ var authorize = (params) => {
269
270
  var PING_TIMEOUT_MS = 3e4;
270
271
  var IORoom = class {
271
272
  constructor(id, config) {
272
- this._doc = doc();
273
273
  this._sessions = /* @__PURE__ */ new Map();
274
274
  this._uninitialize = null;
275
275
  this._authorize = null;
276
- const { authorize: authorize2, context, debug, events, onDestroy, platform } = config;
276
+ const {
277
+ authorize: authorize2,
278
+ context,
279
+ crdt = noop,
280
+ debug,
281
+ events,
282
+ onDestroy,
283
+ platform
284
+ } = config;
277
285
  this._context = context;
278
286
  this._debug = debug;
287
+ this._docFactory = crdt.doc(() => ({}));
288
+ this._doc = this._docFactory.getEmpty();
279
289
  this._events = events;
280
290
  this._platform = platform;
281
291
  this.id = id;
@@ -478,9 +488,9 @@ var IORoom = class {
478
488
  );
479
489
  this._uninitialize = () => __async(this, null, function* () {
480
490
  this._platform.pubSub.unsubscribe(pubSubId);
481
- const encodedState = this._doc.encodeStateAsUpdate();
491
+ const encodedState = this._doc.getEncodedState();
482
492
  this._doc.destroy();
483
- this._doc = doc();
493
+ this._doc = this._docFactory.getEmpty();
484
494
  this._listeners.onDestroy(__spreadProps(__spreadValues({}, this._context), {
485
495
  encodedState,
486
496
  room: this.id
@@ -731,7 +741,7 @@ var PluvIO = class _PluvIO {
731
741
  }
732
742
  };
733
743
  },
734
- self: (_0, _1) => __async(this, [_0, _1], function* ({ update }, { context, doc: doc2, room }) {
744
+ self: (_0, _1) => __async(this, [_0, _1], function* ({ update }, { context, doc, room }) {
735
745
  var _a, _b;
736
746
  const oldState = yield this._platform.persistance.getStorageState(room);
737
747
  const updates = [
@@ -741,7 +751,7 @@ var PluvIO = class _PluvIO {
741
751
  update
742
752
  ];
743
753
  if (updates.some((_update) => !!_update)) {
744
- const encodedState = updates.reduce((_doc, _up) => _doc.applyUpdate(_up), doc2).encodeStateAsUpdate();
754
+ const encodedState = doc.batchApplyEncodedState(updates).getEncodedState();
745
755
  yield this._platform.persistance.setStorageState(
746
756
  room,
747
757
  encodedState
@@ -753,7 +763,7 @@ var PluvIO = class _PluvIO {
753
763
  }
754
764
  const state = (_b = yield this._platform.persistance.getStorageState(
755
765
  room
756
- )) != null ? _b : doc2.encodeStateAsUpdate();
766
+ )) != null ? _b : doc.getEncodedState();
757
767
  return { $STORAGE_RECEIVED: { state } };
758
768
  })
759
769
  }
@@ -782,12 +792,12 @@ var PluvIO = class _PluvIO {
782
792
  }
783
793
  },
784
794
  $UPDATE_STORAGE: {
785
- resolver: ({ origin, update }, { context, doc: doc2, room }) => {
786
- if (origin === "$INITIALIZED" && Object.keys(doc2.toJSON()).length) {
795
+ resolver: ({ origin, update }, { context, doc, room }) => {
796
+ if (origin === "$INITIALIZED" && Object.keys(doc.toJson()).length) {
787
797
  return;
788
798
  }
789
- const updated = doc2.applyUpdate(update);
790
- const encodedState = updated.encodeStateAsUpdate();
799
+ const updated = doc.applyEncodedState({ update });
800
+ const encodedState = updated.getEncodedState();
791
801
  this._platform.persistance.setStorageState(room, encodedState).then(() => {
792
802
  this._listeners.onStorageUpdated(__spreadProps(__spreadValues({}, context), {
793
803
  encodedState,
@@ -802,6 +812,7 @@ var PluvIO = class _PluvIO {
802
812
  const {
803
813
  authorize: authorize2,
804
814
  context,
815
+ crdt = noop2,
805
816
  debug = false,
806
817
  events,
807
818
  getInitialStorage,
@@ -809,6 +820,7 @@ var PluvIO = class _PluvIO {
809
820
  onStorageUpdated,
810
821
  platform
811
822
  } = options;
823
+ this._crdt = crdt;
812
824
  this._debug = debug;
813
825
  this._platform = platform;
814
826
  if (authorize2)
@@ -847,6 +859,7 @@ var PluvIO = class _PluvIO {
847
859
  return _PluvIO.merge(
848
860
  this,
849
861
  new _PluvIO({
862
+ crdt: this._crdt,
850
863
  events: newEvent,
851
864
  platform: this._platform
852
865
  })
@@ -867,6 +880,7 @@ var PluvIO = class _PluvIO {
867
880
  const newRoom = new IORoom(room, {
868
881
  authorize: (_b = this._authorize) != null ? _b : void 0,
869
882
  context: roomContext,
883
+ crdt: this._crdt,
870
884
  debug: debug != null ? debug : this._debug,
871
885
  events: this._events,
872
886
  onDestroy: ({ encodedState, room: room2 }) => {
@@ -905,6 +919,7 @@ var PluvIO = class _PluvIO {
905
919
  var _a;
906
920
  const authorize2 = (_a = first._authorize) != null ? _a : void 0;
907
921
  const context = first._context;
922
+ const crdt = first._crdt;
908
923
  const debug = first._debug;
909
924
  const platform = first._platform;
910
925
  const getInitialStorage = first._getInitialStorage;
@@ -915,6 +930,7 @@ var PluvIO = class _PluvIO {
915
930
  return new _PluvIO({
916
931
  authorize: authorize2,
917
932
  context,
933
+ crdt,
918
934
  debug,
919
935
  events,
920
936
  getInitialStorage,
@@ -941,6 +957,7 @@ var createIO = (params) => {
941
957
  const {
942
958
  authorize: authorize2,
943
959
  context,
960
+ crdt,
944
961
  debug,
945
962
  getInitialStorage,
946
963
  onRoomDeleted,
@@ -950,6 +967,7 @@ var createIO = (params) => {
950
967
  return new PluvIO({
951
968
  authorize: authorize2,
952
969
  context,
970
+ crdt,
953
971
  debug,
954
972
  getInitialStorage,
955
973
  onRoomDeleted,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pluv/io",
3
- "version": "0.14.1",
3
+ "version": "0.16.0",
4
4
  "description": "@pluv/io server-side websocket manager",
5
5
  "author": "leedavidcs",
6
6
  "license": "MIT",
@@ -18,22 +18,18 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@panva/hkdf": "^1.1.1",
21
- "jose": "^5.1.3",
21
+ "jose": "^5.2.2",
22
22
  "kleur": "^4.1.5",
23
23
  "wonka": "^6.3.4",
24
- "@pluv/crdt-yjs": "^0.14.1",
25
- "@pluv/types": "^0.14.1"
26
- },
27
- "peerDependencies": {
28
- "yjs": "^13.0.0"
24
+ "@pluv/crdt": "^0.16.0",
25
+ "@pluv/types": "^0.16.0"
29
26
  },
30
27
  "devDependencies": {
31
28
  "eslint": "^8.56.0",
32
- "tsup": "^8.0.1",
33
- "typescript": "^5.2.2",
34
- "yjs": "^13.6.10",
35
- "@pluv/tsconfig": "^0.14.1",
36
- "eslint-config-pluv": "^0.14.1"
29
+ "tsup": "^8.0.2",
30
+ "typescript": "^5.3.3",
31
+ "@pluv/tsconfig": "^0.16.0",
32
+ "eslint-config-pluv": "^0.16.0"
37
33
  },
38
34
  "scripts": {
39
35
  "build": "tsup src/index.ts --format esm,cjs --dts",
@@ -1,4 +1,4 @@
1
- import { JsonObject } from "@pluv/types";
1
+ import type { JsonObject } from "@pluv/types";
2
2
 
3
3
  export abstract class AbstractPersistance {
4
4
  public abstract addUser(
package/src/IORoom.ts CHANGED
@@ -1,17 +1,17 @@
1
- import type { YjsDoc } from "@pluv/crdt-yjs";
2
- import { doc } from "@pluv/crdt-yjs";
1
+ import type { AbstractCrdtDoc, AbstractCrdtDocFactory } from "@pluv/crdt";
2
+ import { noop } from "@pluv/crdt";
3
3
  import type {
4
4
  BaseIOAuthorize,
5
5
  BaseIOEventRecord,
6
6
  EventMessage,
7
7
  EventRecord,
8
+ IOAuthorize,
9
+ IOLike,
8
10
  Id,
9
11
  InferEventMessage,
10
12
  InferIOAuthorize,
11
13
  InferIOAuthorizeUser,
12
14
  InferIOInput,
13
- IOAuthorize,
14
- IOLike,
15
15
  JsonObject,
16
16
  Maybe,
17
17
  } from "@pluv/types";
@@ -64,6 +64,7 @@ export type IORoomConfig<
64
64
  > = Partial<IORoomListeners<TPlatform>> & {
65
65
  authorize?: TAuthorize;
66
66
  context: TContext & InferPlatformRoomContextType<TPlatform>;
67
+ crdt?: { doc: (value: any) => AbstractCrdtDocFactory<any> };
67
68
  debug: boolean;
68
69
  events: InferEventConfig<
69
70
  TPlatform,
@@ -100,9 +101,10 @@ export class IORoom<
100
101
  private readonly _context: TContext &
101
102
  InferPlatformRoomContextType<TPlatform>;
102
103
  private readonly _debug: boolean;
104
+ private readonly _docFactory: AbstractCrdtDocFactory<any>;
103
105
  private readonly _platform: TPlatform;
104
106
 
105
- private _doc: YjsDoc<any> = doc();
107
+ private _doc: AbstractCrdtDoc<any>;
106
108
  private _listeners: IORoomListeners<TPlatform>;
107
109
  private _sessions = new Map<string, WebSocketSession>();
108
110
  private _uninitialize: (() => Promise<void>) | null = null;
@@ -131,11 +133,20 @@ export class IORoom<
131
133
  TOutputSync
132
134
  >,
133
135
  ) {
134
- const { authorize, context, debug, events, onDestroy, platform } =
135
- config;
136
+ const {
137
+ authorize,
138
+ context,
139
+ crdt = noop,
140
+ debug,
141
+ events,
142
+ onDestroy,
143
+ platform,
144
+ } = config;
136
145
 
137
146
  this._context = context;
138
147
  this._debug = debug;
148
+ this._docFactory = crdt.doc(() => ({}));
149
+ this._doc = this._docFactory.getEmpty();
139
150
  this._events = events;
140
151
  this._platform = platform;
141
152
 
@@ -449,10 +460,10 @@ export class IORoom<
449
460
  this._uninitialize = async () => {
450
461
  this._platform.pubSub.unsubscribe(pubSubId);
451
462
 
452
- const encodedState = this._doc.encodeStateAsUpdate();
463
+ const encodedState = this._doc.getEncodedState();
453
464
 
454
465
  this._doc.destroy();
455
- this._doc = doc();
466
+ this._doc = this._docFactory.getEmpty();
456
467
 
457
468
  this._listeners.onDestroy({
458
469
  ...this._context,
package/src/PluvIO.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import type { AbstractCrdtDocFactory } from "@pluv/crdt";
2
+ import { noop } from "@pluv/crdt";
1
3
  import type {
2
4
  BaseIOAuthorize,
3
5
  EventRecord,
@@ -19,7 +21,8 @@ import type {
19
21
  AbstractPlatform,
20
22
  InferPlatformRoomContextType,
21
23
  } from "./AbstractPlatform";
22
- import { IORoom, IORoomListenerEvent } from "./IORoom";
24
+ import type { IORoomListenerEvent } from "./IORoom";
25
+ import { IORoom } from "./IORoom";
23
26
  import type { JWTEncodeParams } from "./authorize";
24
27
  import { authorize } from "./authorize";
25
28
  import type { EventConfig, InferEventConfig } from "./types";
@@ -79,6 +82,7 @@ export type PluvIOConfig<
79
82
  > = Partial<PluvIOListeners<TPlatform>> & {
80
83
  authorize?: TAuthorize;
81
84
  context?: TContext;
85
+ crdt?: { doc: (value: any) => AbstractCrdtDocFactory<any> };
82
86
  debug?: boolean;
83
87
  events?: InferEventConfig<
84
88
  TPlatform,
@@ -122,6 +126,7 @@ export class PluvIO<
122
126
 
123
127
  readonly _authorize: TAuthorize | null = null;
124
128
  readonly _context: TContext = {} as TContext;
129
+ readonly _crdt: { doc: (value: any) => AbstractCrdtDocFactory<any> };
125
130
  readonly _debug: boolean;
126
131
  readonly _events: InferEventConfig<
127
132
  TPlatform,
@@ -189,9 +194,9 @@ export class PluvIO<
189
194
  ];
190
195
 
191
196
  if (updates.some((_update) => !!_update)) {
192
- const encodedState = updates
193
- .reduce((_doc, _up) => _doc.applyUpdate(_up), doc)
194
- .encodeStateAsUpdate();
197
+ const encodedState = doc
198
+ .batchApplyEncodedState(updates)
199
+ .getEncodedState();
195
200
 
196
201
  await this._platform.persistance.setStorageState(
197
202
  room,
@@ -208,7 +213,7 @@ export class PluvIO<
208
213
  const state =
209
214
  (await this._platform.persistance.getStorageState(
210
215
  room,
211
- )) ?? doc.encodeStateAsUpdate();
216
+ )) ?? doc.getEncodedState();
212
217
 
213
218
  return { $STORAGE_RECEIVED: { state } };
214
219
  },
@@ -244,13 +249,13 @@ export class PluvIO<
244
249
  resolver: ({ origin, update }, { context, doc, room }) => {
245
250
  if (
246
251
  origin === "$INITIALIZED" &&
247
- Object.keys(doc.toJSON()).length
252
+ Object.keys(doc.toJson()).length
248
253
  ) {
249
254
  return;
250
255
  }
251
256
 
252
- const updated = doc.applyUpdate(update);
253
- const encodedState = updated.encodeStateAsUpdate();
257
+ const updated = doc.applyEncodedState({ update });
258
+ const encodedState = updated.getEncodedState();
254
259
 
255
260
  this._platform.persistance
256
261
  .setStorageState(room, encodedState)
@@ -291,6 +296,7 @@ export class PluvIO<
291
296
  const {
292
297
  authorize,
293
298
  context,
299
+ crdt = noop,
294
300
  debug = false,
295
301
  events,
296
302
  getInitialStorage,
@@ -299,6 +305,7 @@ export class PluvIO<
299
305
  platform,
300
306
  } = options;
301
307
 
308
+ this._crdt = crdt;
302
309
  this._debug = debug;
303
310
  this._platform = platform;
304
311
 
@@ -386,6 +393,7 @@ export class PluvIO<
386
393
  return PluvIO.merge(
387
394
  this as any,
388
395
  new PluvIO({
396
+ crdt: this._crdt,
389
397
  events: newEvent as any,
390
398
  platform: this._platform,
391
399
  }),
@@ -433,6 +441,7 @@ export class PluvIO<
433
441
  >(room, {
434
442
  authorize: this._authorize ?? undefined,
435
443
  context: roomContext,
444
+ crdt: this._crdt,
436
445
  debug: debug ?? this._debug,
437
446
  events: this._events,
438
447
  onDestroy: ({ encodedState, room }) => {
@@ -493,6 +502,7 @@ export class PluvIO<
493
502
  const authorize = (first._authorize ??
494
503
  undefined) as InferIOAuthorize<TIO1>;
495
504
  const context = first._context as InferIOContext<TIO1>;
505
+ const crdt = first._crdt;
496
506
  const debug = first._debug;
497
507
  const platform = first._platform as InferIOPlatform<TIO1>;
498
508
 
@@ -511,6 +521,7 @@ export class PluvIO<
511
521
  return new PluvIO({
512
522
  authorize,
513
523
  context,
524
+ crdt,
514
525
  debug,
515
526
  events,
516
527
  getInitialStorage,
package/src/authorize.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import hkdf from "@panva/hkdf";
2
- import { BaseUser } from "@pluv/types";
2
+ import type { BaseUser } from "@pluv/types";
3
3
  import { EncryptJWT, jwtDecrypt } from "jose";
4
- import { AbstractPlatform } from "./AbstractPlatform";
4
+ import type { AbstractPlatform } from "./AbstractPlatform";
5
5
 
6
6
  const DEFAULT_MAX_AGE_MS = 60_000;
7
7
 
package/src/createIO.ts CHANGED
@@ -1,11 +1,10 @@
1
+ import type { AbstractCrdtDocFactory } from "@pluv/crdt";
1
2
  import type {
2
3
  BaseClientEventRecord,
3
4
  BaseIOEventRecord,
4
5
  BaseUser,
5
6
  IOAuthorize,
6
7
  JsonObject,
7
- Maybe,
8
- MaybePromise,
9
8
  } from "@pluv/types";
10
9
  import type { AbstractPlatform } from "./AbstractPlatform";
11
10
  import type { GetInitialStorageFn, PluvIOListeners } from "./PluvIO";
@@ -19,6 +18,7 @@ export type CreateIOParams<
19
18
  > = Partial<PluvIOListeners<TPlatform>> & {
20
19
  authorize?: IOAuthorize<TAuthorizeUser, TAuthorizeRequired>;
21
20
  context?: TContext;
21
+ crdt?: { doc: (value: any) => AbstractCrdtDocFactory<any> };
22
22
  debug?: boolean;
23
23
  getInitialStorage?: GetInitialStorageFn<TPlatform>;
24
24
  platform: TPlatform;
@@ -46,6 +46,7 @@ export const createIO = <
46
46
  const {
47
47
  authorize,
48
48
  context,
49
+ crdt,
49
50
  debug,
50
51
  getInitialStorage,
51
52
  onRoomDeleted,
@@ -62,6 +63,7 @@ export const createIO = <
62
63
  >({
63
64
  authorize,
64
65
  context,
66
+ crdt,
65
67
  debug,
66
68
  getInitialStorage,
67
69
  onRoomDeleted,
package/src/types.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { YjsDoc } from "@pluv/crdt-yjs";
1
+ import type { AbstractCrdtDoc } from "@pluv/crdt";
2
2
  import type {
3
3
  EventRecord,
4
4
  Id,
@@ -13,14 +13,6 @@ import {
13
13
  } from "./AbstractPlatform";
14
14
  import type { AbstractWebSocket } from "./AbstractWebSocket";
15
15
 
16
- export interface Console {
17
- debug(...data: any[]): void;
18
- error(...data: any[]): void;
19
- info(...data: any[]): void;
20
- log(...data: any[]): void;
21
- warn(...data: any[]): void;
22
- }
23
-
24
16
  declare global {
25
17
  var console: {
26
18
  log: (...data: any[]) => void;
@@ -78,7 +70,7 @@ export interface EventResolverContext<
78
70
  TContext extends Record<string, any> = {},
79
71
  > {
80
72
  context: TContext;
81
- doc: YjsDoc<any>;
73
+ doc: AbstractCrdtDoc<any>;
82
74
  room: string;
83
75
  /**
84
76
  * !HACK