@pluv/crdt-yjs 3.2.2 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,611 +1,591 @@
1
- var __defProp = Object.defineProperty;
2
- var __defProps = Object.defineProperties;
3
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
- var __typeError = (msg) => {
8
- throw TypeError(msg);
9
- };
10
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
- var __spreadValues = (a, b) => {
12
- for (var prop in b || (b = {}))
13
- if (__hasOwnProp.call(b, prop))
14
- __defNormalProp(a, prop, b[prop]);
15
- if (__getOwnPropSymbols)
16
- for (var prop of __getOwnPropSymbols(b)) {
17
- if (__propIsEnum.call(b, prop))
18
- __defNormalProp(a, prop, b[prop]);
19
- }
20
- return a;
21
- };
22
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
23
- var __export = (target, all) => {
24
- for (var name in all)
25
- __defProp(target, name, { get: all[name], enumerable: true });
26
- };
27
- var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
28
- var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
29
- var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
30
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
31
- var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
32
-
33
- // src/yjs.ts
34
- var yjs_exports = {};
35
- __export(yjs_exports, {
36
- array: () => array,
37
- awareness: () => awareness,
38
- doc: () => doc,
39
- kind: () => kind,
40
- map: () => map,
41
- provider: () => provider,
42
- text: () => text,
43
- xmlElement: () => xmlElement,
44
- xmlFragment: () => xmlFragment,
45
- xmlText: () => xmlText
46
- });
1
+ import { t as __exportAll } from "./chunk-15K8U1wQ.mjs";
2
+ import { Array, Doc, Map as Map$1, Text, UndoManager, XmlElement, XmlFragment, XmlText, applyUpdate, encodeStateAsUpdate, mergeUpdates } from "yjs";
3
+ import { ObservableV2 } from "lib0/observable";
4
+ import { fromUint8Array, toUint8Array } from "js-base64";
5
+ import { AbstractCrdtDocFactory } from "@pluv/crdt";
6
+ import { StorageState } from "@pluv/types";
47
7
 
48
- // src/array/YjsArray.ts
49
- import { Array as YArray } from "yjs";
50
- var YjsArray = class extends YArray {
51
- constructor(value = []) {
52
- super();
53
- this.insert(0, value);
54
- this.initialValue = value;
55
- }
56
- __pluvType() {
57
- return {};
58
- }
8
+ //#region src/array/YjsArray.ts
9
+ var YjsArray = class extends Array {
10
+ initialValue;
11
+ constructor(value = []) {
12
+ super();
13
+ this.insert(0, value);
14
+ this.initialValue = value;
15
+ }
16
+ __pluvType() {
17
+ return {};
18
+ }
59
19
  };
60
20
 
61
- // src/array/array.ts
62
- var array = (value = []) => {
63
- return new YjsArray(value);
21
+ //#endregion
22
+ //#region src/array/array.ts
23
+ const array = (value = []) => {
24
+ return new YjsArray(value);
64
25
  };
65
26
 
66
- // src/awareness/PluvYjsAwareness.ts
67
- import { ObservableV2 } from "lib0/observable";
27
+ //#endregion
28
+ //#region src/constants.ts
29
+ const PLUV_PRESENCE_META_KEY = "__pluv";
30
+ const PLUV_PRESENCE_Y_ID_KEY = "__y_clientid";
68
31
 
69
- // src/constants.ts
70
- var PLUV_PRESENCE_META_KEY = "__pluv";
71
- var PLUV_PRESENCE_Y_ID_KEY = "__y_clientid";
72
-
73
- // src/awareness/PluvYjsAwareness.ts
32
+ //#endregion
33
+ //#region src/awareness/PluvYjsAwareness.ts
74
34
  var PluvYjsAwareness = class extends ObservableV2 {
75
- constructor(params) {
76
- super();
77
- this._field = null;
78
- this._idMap = /* @__PURE__ */ new Map();
79
- /**
80
- * !HACK
81
- * @description We dgaf about these. We're just mirroring the fields that exist in the
82
- * og awareness to make sure everything aligns.
83
- * @see https://github.com/yjs/y-protocols/blob/master/awareness.js
84
- * @date May 13, 2025
85
- */
86
- this.meta = /* @__PURE__ */ new Map();
87
- this._checkInterval = 0;
88
- const { presenceField, room } = params;
89
- this.doc = room.getDoc().value;
90
- this._room = room;
91
- if (!!presenceField) this._field = presenceField;
92
- const myPresence = this._room.getMyPresence();
93
- const myMeta = (myPresence == null ? void 0 : myPresence[PLUV_PRESENCE_META_KEY]) || {};
94
- this._room.updateMyPresence({
95
- [PLUV_PRESENCE_META_KEY]: __spreadProps(__spreadValues({}, myMeta), {
96
- [PLUV_PRESENCE_Y_ID_KEY]: this.clientID
97
- })
98
- });
99
- this._unsubscribe = this._room.subscribe.others((others, event) => {
100
- const updates = this._deriveUpdates(others, event);
101
- if (!updates) return;
102
- this.emit("change", [updates, "presence"]);
103
- this.emit("update", [updates, "presence"]);
104
- });
105
- }
106
- get clientID() {
107
- return this.doc.clientID;
108
- }
109
- get states() {
110
- return this.getStates();
111
- }
112
- destroy() {
113
- this.emit("destroy", [this]);
114
- this._unsubscribe();
115
- super.destroy();
116
- }
117
- getLocalState() {
118
- return this._adaptPresence(this._room.getMyPresence());
119
- }
120
- setLocalState(state) {
121
- const patch = !!this._field ? { [this._field]: state } : state;
122
- this._room.updateMyPresence(patch);
123
- this.emit("update", [{ added: [], updated: [this.clientID], removed: [] }, "local"]);
124
- }
125
- setLocalStateField(field, value) {
126
- const patch = !!this._field ? { [this._field]: __spreadProps(__spreadValues({}, this.getLocalState()), { [field]: value }) } : { [field]: value };
127
- this._room.updateMyPresence(patch);
128
- }
129
- /**
130
- * !HACK
131
- * @description We're building the awareness presences from the states stored on the room's
132
- * presense instead of using the map defined in the awareness interface.
133
- * @see https://github.com/yjs/y-protocols/blob/master/awareness.js
134
- * @date May 13, 2025
135
- */
136
- getStates() {
137
- const others = this._room.getOthers();
138
- const states = others.reduce((map2, other) => {
139
- var _a;
140
- const presence = this._adaptPresence(other.presence);
141
- const meta = ((_a = other.presence) == null ? void 0 : _a[PLUV_PRESENCE_META_KEY]) || {};
142
- const clientID = meta[PLUV_PRESENCE_Y_ID_KEY];
143
- return typeof presence !== "undefined" && typeof clientID !== "undefined" ? map2.set(clientID, presence) : map2;
144
- }, /* @__PURE__ */ new Map());
145
- const myPresence = this.getLocalState();
146
- if (typeof myPresence !== "undefined") states.set(this.clientID, myPresence);
147
- return states;
148
- }
149
- _adaptPresence(presence) {
150
- return !!this._field ? presence[this._field] : presence;
151
- }
152
- _deriveUpdates(others, event) {
153
- switch (event.kind) {
154
- case "clear": {
155
- this._idMap.clear();
156
- return null;
157
- }
158
- case "enter": {
159
- const clientID = this._resetIdMap(others).get(event.user.connectionId);
160
- return {
161
- added: typeof clientID !== "undefined" ? [clientID] : [],
162
- updated: [],
163
- removed: []
164
- };
165
- }
166
- case "leave": {
167
- const clientID = this._idMap.get(event.user.connectionId);
168
- this._resetIdMap(others);
169
- return {
170
- added: [],
171
- updated: [],
172
- removed: typeof clientID !== "undefined" ? [clientID] : []
173
- };
174
- }
175
- case "sync": {
176
- this._resetIdMap(others);
177
- return null;
178
- }
179
- case "update": {
180
- const clientID = this._resetIdMap(others).get(event.user.connectionId);
181
- return {
182
- added: [],
183
- updated: typeof clientID !== "undefined" ? [clientID] : [],
184
- removed: []
185
- };
186
- }
187
- default:
188
- return null;
189
- }
190
- }
191
- _resetIdMap(others) {
192
- this._idMap.clear();
193
- return others.reduce((map2, other) => {
194
- var _a;
195
- const clientID = (_a = other.presence[PLUV_PRESENCE_META_KEY]) == null ? void 0 : _a[PLUV_PRESENCE_Y_ID_KEY];
196
- if (typeof clientID === "undefined") return map2;
197
- return map2.set(other.connectionId, clientID);
198
- }, this._idMap);
199
- }
35
+ doc;
36
+ _field = null;
37
+ _idMap = /* @__PURE__ */ new Map();
38
+ _room;
39
+ _unsubscribe;
40
+ get clientID() {
41
+ return this.doc.clientID;
42
+ }
43
+ get states() {
44
+ return this.getStates();
45
+ }
46
+ constructor(params) {
47
+ super();
48
+ const { presenceField, room } = params;
49
+ this.doc = room.getDoc().value;
50
+ this._room = room;
51
+ if (!!presenceField) this._field = presenceField;
52
+ const myMeta = this._room.getMyPresence()?.[PLUV_PRESENCE_META_KEY] || {};
53
+ this._room.updateMyPresence({ [PLUV_PRESENCE_META_KEY]: {
54
+ ...myMeta,
55
+ [PLUV_PRESENCE_Y_ID_KEY]: this.clientID
56
+ } });
57
+ this._unsubscribe = this._room.subscribe.others((others, event) => {
58
+ const updates = this._deriveUpdates(others, event);
59
+ if (!updates) return;
60
+ this.emit("change", [updates, "presence"]);
61
+ this.emit("update", [updates, "presence"]);
62
+ });
63
+ }
64
+ destroy() {
65
+ this.emit("destroy", [this]);
66
+ this._unsubscribe();
67
+ super.destroy();
68
+ }
69
+ getLocalState() {
70
+ return this._adaptPresence(this._room.getMyPresence());
71
+ }
72
+ setLocalState(state) {
73
+ const patch = !!this._field ? { [this._field]: state } : state;
74
+ this._room.updateMyPresence(patch);
75
+ this.emit("update", [{
76
+ added: [],
77
+ updated: [this.clientID],
78
+ removed: []
79
+ }, "local"]);
80
+ }
81
+ setLocalStateField(field, value) {
82
+ /**
83
+ * !HACK
84
+ * @description Cast to unknown first, because field loses its type of TField when set in
85
+ * an object.
86
+ * @date May 14, 2025
87
+ */
88
+ const patch = !!this._field ? { [this._field]: {
89
+ ...this.getLocalState(),
90
+ [field]: value
91
+ } } : { [field]: value };
92
+ this._room.updateMyPresence(patch);
93
+ }
94
+ /**
95
+ * !HACK
96
+ * @description We're building the awareness presences from the states stored on the room's
97
+ * presense instead of using the map defined in the awareness interface.
98
+ * @see https://github.com/yjs/y-protocols/blob/master/awareness.js
99
+ * @date May 13, 2025
100
+ */
101
+ getStates() {
102
+ const states = this._room.getOthers().reduce((map$1, other) => {
103
+ const presence = this._adaptPresence(other.presence);
104
+ const clientID = (other.presence?.[PLUV_PRESENCE_META_KEY] || {})[PLUV_PRESENCE_Y_ID_KEY];
105
+ return typeof presence !== "undefined" && typeof clientID !== "undefined" ? map$1.set(clientID, presence) : map$1;
106
+ }, /* @__PURE__ */ new Map());
107
+ const myPresence = this.getLocalState();
108
+ if (typeof myPresence !== "undefined") states.set(this.clientID, myPresence);
109
+ return states;
110
+ }
111
+ _adaptPresence(presence) {
112
+ return !!this._field ? presence[this._field] : presence;
113
+ }
114
+ _deriveUpdates(others, event) {
115
+ switch (event.kind) {
116
+ case "clear":
117
+ this._idMap.clear();
118
+ return null;
119
+ case "enter": {
120
+ const clientID = this._resetIdMap(others).get(event.user.connectionId);
121
+ return {
122
+ added: typeof clientID !== "undefined" ? [clientID] : [],
123
+ updated: [],
124
+ removed: []
125
+ };
126
+ }
127
+ case "leave": {
128
+ const clientID = this._idMap.get(event.user.connectionId);
129
+ this._resetIdMap(others);
130
+ return {
131
+ added: [],
132
+ updated: [],
133
+ removed: typeof clientID !== "undefined" ? [clientID] : []
134
+ };
135
+ }
136
+ case "sync":
137
+ this._resetIdMap(others);
138
+ return null;
139
+ case "update": {
140
+ const clientID = this._resetIdMap(others).get(event.user.connectionId);
141
+ return {
142
+ added: [],
143
+ updated: typeof clientID !== "undefined" ? [clientID] : [],
144
+ removed: []
145
+ };
146
+ }
147
+ default: return null;
148
+ }
149
+ }
150
+ _resetIdMap(others) {
151
+ this._idMap.clear();
152
+ return others.reduce((map$1, other) => {
153
+ const clientID = other.presence[PLUV_PRESENCE_META_KEY]?.[PLUV_PRESENCE_Y_ID_KEY];
154
+ if (typeof clientID === "undefined") return map$1;
155
+ return map$1.set(other.connectionId, clientID);
156
+ }, this._idMap);
157
+ }
158
+ /**
159
+ * !HACK
160
+ * @description We dgaf about these. We're just mirroring the fields that exist in the
161
+ * og awareness to make sure everything aligns.
162
+ * @see https://github.com/yjs/y-protocols/blob/master/awareness.js
163
+ * @date May 13, 2025
164
+ */
165
+ meta = /* @__PURE__ */ new Map();
166
+ _checkInterval = 0;
200
167
  };
201
168
 
202
- // src/awareness/awareness.ts
203
- var awareness = (params) => {
204
- return new PluvYjsAwareness(params);
169
+ //#endregion
170
+ //#region src/awareness/awareness.ts
171
+ const awareness = (params) => {
172
+ return new PluvYjsAwareness(params);
205
173
  };
206
174
 
207
- // src/doc/CrdtYjsDoc.ts
208
- import { fromUint8Array, toUint8Array } from "js-base64";
209
- import {
210
- UndoManager,
211
- Array as YArray3,
212
- Doc as YDoc2,
213
- Map as YMap2,
214
- Text as YText2,
215
- XmlElement as YXmlElement2,
216
- XmlFragment as YXmlFragment2,
217
- XmlText as YXmlText2,
218
- applyUpdate,
219
- encodeStateAsUpdate,
220
- mergeUpdates
221
- } from "yjs";
222
-
223
- // src/doc/builder.ts
224
- import {
225
- XmlText as YXmlText
226
- } from "yjs";
227
- var builder = (doc2) => {
228
- return {
229
- array(name, value = []) {
230
- const array2 = doc2.getArray(name);
231
- if (!!value.length) array2.insert(0, value);
232
- return array2;
233
- },
234
- map(name, value = []) {
235
- const map2 = doc2.getMap(name);
236
- value.forEach(([k, v]) => {
237
- map2.set(k, v);
238
- });
239
- return map2;
240
- },
241
- text(name, value = "") {
242
- const text2 = doc2.getText(name);
243
- if (!!value) text2.insert(0, value);
244
- return text2;
245
- },
246
- xmlElement(name, children = []) {
247
- const xmlElement2 = doc2.getXmlElement(name);
248
- if (!!children.length) xmlElement2.insert(0, children);
249
- return xmlElement2;
250
- },
251
- xmlFragment(name, children = []) {
252
- const xmlFragment2 = doc2.getXmlFragment(name);
253
- if (!!children.length) xmlFragment2.insert(0, children);
254
- return xmlFragment2;
255
- },
256
- xmlText(name) {
257
- const xmlText2 = doc2.get(name, YXmlText);
258
- return xmlText2;
259
- }
260
- };
175
+ //#endregion
176
+ //#region src/doc/builder.ts
177
+ const builder = (doc$1) => {
178
+ return {
179
+ array(name, value = []) {
180
+ const array$1 = doc$1.getArray(name);
181
+ if (!!value.length) array$1.insert(0, value);
182
+ return array$1;
183
+ },
184
+ map(name, value = []) {
185
+ const map$1 = doc$1.getMap(name);
186
+ value.forEach(([k, v]) => {
187
+ map$1.set(k, v);
188
+ });
189
+ return map$1;
190
+ },
191
+ text(name, value = "") {
192
+ const text$1 = doc$1.getText(name);
193
+ if (!!value) text$1.insert(0, value);
194
+ return text$1;
195
+ },
196
+ xmlElement(name, children = []) {
197
+ const xmlElement$1 = doc$1.getXmlElement(name);
198
+ if (!!children.length) xmlElement$1.insert(0, children);
199
+ return xmlElement$1;
200
+ },
201
+ xmlFragment(name, children = []) {
202
+ const xmlFragment$1 = doc$1.getXmlFragment(name);
203
+ if (!!children.length) xmlFragment$1.insert(0, children);
204
+ return xmlFragment$1;
205
+ },
206
+ xmlText(name) {
207
+ return doc$1.get(name, XmlText);
208
+ }
209
+ };
261
210
  };
262
211
 
263
- // src/doc/CrdtYjsDoc.ts
264
- var MERGE_INTERVAL_MS = 1e3;
265
- var PLUV_ID_FIELD = "__$pluv";
266
- var __storage, __undoManager, _CrdtYjsDoc_instances, _setPluvId_fn;
212
+ //#endregion
213
+ //#region src/doc/CrdtYjsDoc.ts
214
+ const MERGE_INTERVAL_MS = 1e3;
215
+ const PLUV_ID_FIELD = "__$pluv";
267
216
  var CrdtYjsDoc = class {
268
- constructor(params = () => ({})) {
269
- __privateAdd(this, _CrdtYjsDoc_instances);
270
- this.value = new YDoc2();
271
- __privateAdd(this, __storage);
272
- __privateAdd(this, __undoManager, null);
273
- const storage = params(builder(this.value));
274
- const keys = this.value.share.keys().reduce((set, key) => set.add(key), /* @__PURE__ */ new Set());
275
- __privateSet(this, __storage, Object.entries(storage).reduce(
276
- (acc, [key, node]) => keys.has(key) ? __spreadProps(__spreadValues({}, acc), { [key]: node }) : acc,
277
- {}
278
- ));
279
- if (!!Object.keys(storage).length) __privateMethod(this, _CrdtYjsDoc_instances, _setPluvId_fn).call(this);
280
- }
281
- applyEncodedState(params) {
282
- const { origin, update } = params;
283
- if (update === null || typeof update === "undefined") return this;
284
- const uint8Update = typeof update === "string" ? toUint8Array(update) : update;
285
- applyUpdate(this.value, uint8Update, origin);
286
- return this;
287
- }
288
- batchApplyEncodedState(params) {
289
- var _a;
290
- const { origin } = params;
291
- const updates = (_a = params.updates) != null ? _a : [];
292
- const filtered = updates.reduce((acc, update) => {
293
- if (!update) return acc;
294
- if (typeof update === "string") {
295
- acc.push(toUint8Array(update));
296
- return acc;
297
- }
298
- if (typeof update === "object") {
299
- acc.push(update);
300
- return acc;
301
- }
302
- return acc;
303
- }, []);
304
- if (!filtered.length) return this;
305
- const merged = mergeUpdates(filtered);
306
- return this.applyEncodedState({ origin, update: merged });
307
- }
308
- canRedo() {
309
- var _a;
310
- return !!((_a = __privateGet(this, __undoManager)) == null ? void 0 : _a.canRedo());
311
- }
312
- canUndo() {
313
- var _a;
314
- return !!((_a = __privateGet(this, __undoManager)) == null ? void 0 : _a.canUndo());
315
- }
316
- destroy() {
317
- var _a;
318
- (_a = __privateGet(this, __undoManager)) == null ? void 0 : _a.destroy();
319
- this.value.destroy();
320
- }
321
- get(type) {
322
- if (typeof type === "undefined") return __privateGet(this, __storage);
323
- return __privateGet(this, __storage)[type];
324
- }
325
- getEncodedState() {
326
- return fromUint8Array(encodeStateAsUpdate(this.value));
327
- }
328
- isEmpty() {
329
- return !this.value.share.size;
330
- }
331
- rebuildStorage(reference) {
332
- const isBuilt = !!Object.keys(__privateGet(this, __storage)).length;
333
- if (isBuilt) {
334
- console.warn("Attempted to rebuild storage multiple times");
335
- return this;
336
- }
337
- __privateSet(this, __storage, Object.entries(reference).reduce((acc, [key, node]) => {
338
- if (node instanceof YXmlElement2) {
339
- return __spreadProps(__spreadValues({}, acc), { [key]: this.value.getXmlElement(key) });
340
- }
341
- if (node instanceof YXmlFragment2) {
342
- return __spreadProps(__spreadValues({}, acc), { [key]: this.value.getXmlFragment(key) });
343
- }
344
- if (node instanceof YXmlText2) return __spreadProps(__spreadValues({}, acc), { [key]: this.value.get(key, YXmlText2) });
345
- if (node instanceof YArray3) return __spreadProps(__spreadValues({}, acc), { [key]: this.value.getArray(key) });
346
- if (node instanceof YMap2) return __spreadProps(__spreadValues({}, acc), { [key]: this.value.getMap(key) });
347
- if (node instanceof YText2) return __spreadProps(__spreadValues({}, acc), { [key]: this.value.getText(key) });
348
- return acc;
349
- }, {}));
350
- return this.track();
351
- }
352
- redo() {
353
- var _a;
354
- (_a = __privateGet(this, __undoManager)) == null ? void 0 : _a.redo();
355
- return this;
356
- }
357
- subscribe(listener) {
358
- const fn = (update, origin, doc2) => {
359
- listener({
360
- doc: this,
361
- local: origin === null || typeof origin === "undefined",
362
- origin: origin ? String(origin) : null,
363
- update: fromUint8Array(update)
364
- });
365
- };
366
- this.value.on("update", fn);
367
- return () => {
368
- this.value.off("update", fn);
369
- };
370
- }
371
- track() {
372
- var _a;
373
- if (__privateGet(this, __undoManager)) __privateGet(this, __undoManager).destroy();
374
- const sharedTypes = Object.values(__privateGet(this, __storage)).reduce(
375
- (acc, type) => {
376
- if (type instanceof YArray3 || type instanceof YMap2 || type instanceof YText2 || type instanceof YXmlElement2 || type instanceof YXmlFragment2 || type instanceof YXmlText2) {
377
- acc.push(type);
378
- }
379
- return acc;
380
- },
381
- []
382
- );
383
- if (!sharedTypes.length) {
384
- (_a = __privateGet(this, __undoManager)) == null ? void 0 : _a.destroy();
385
- __privateSet(this, __undoManager, null);
386
- return this;
387
- }
388
- __privateSet(this, __undoManager, new UndoManager(sharedTypes, { captureTimeout: MERGE_INTERVAL_MS }));
389
- return this;
390
- }
391
- transact(fn) {
392
- this.value.transact(fn);
393
- return this;
394
- }
395
- toJson(type) {
396
- if (typeof type === "string") return __privateGet(this, __storage)[type].toJSON();
397
- return Object.entries(__privateGet(this, __storage)).reduce(
398
- (acc, [key, value]) => __spreadProps(__spreadValues({}, acc), { [key]: value.toJSON() }),
399
- {}
400
- );
401
- }
402
- undo() {
403
- var _a;
404
- (_a = __privateGet(this, __undoManager)) == null ? void 0 : _a.undo();
405
- return this;
406
- }
407
- };
408
- __storage = new WeakMap();
409
- __undoManager = new WeakMap();
410
- _CrdtYjsDoc_instances = new WeakSet();
411
- _setPluvId_fn = function() {
412
- const text2 = this.value.getText(PLUV_ID_FIELD);
413
- const id = typeof crypto !== "undefined" ? crypto.randomUUID() : Math.random().toString();
414
- text2.insert(0, id);
217
+ value = new Doc();
218
+ #_storage;
219
+ #_undoManager = null;
220
+ constructor(params = () => ({})) {
221
+ const storage = params(builder(this.value));
222
+ const keys = this.value.share.keys().reduce((set, key) => set.add(key), /* @__PURE__ */ new Set());
223
+ this.#_storage = Object.entries(storage).reduce((acc, [key, node]) => keys.has(key) ? {
224
+ ...acc,
225
+ [key]: node
226
+ } : acc, {});
227
+ if (!!Object.keys(storage).length) this.#_setPluvId();
228
+ }
229
+ applyEncodedState(params) {
230
+ const { origin, update } = params;
231
+ if (update === null || typeof update === "undefined") return this;
232
+ const uint8Update = typeof update === "string" ? toUint8Array(update) : update;
233
+ applyUpdate(this.value, uint8Update, origin);
234
+ return this;
235
+ }
236
+ batchApplyEncodedState(params) {
237
+ const { origin } = params;
238
+ const filtered = (params.updates ?? []).reduce((acc, update) => {
239
+ if (!update) return acc;
240
+ if (typeof update === "string") {
241
+ acc.push(toUint8Array(update));
242
+ return acc;
243
+ }
244
+ if (typeof update === "object") {
245
+ acc.push(update);
246
+ return acc;
247
+ }
248
+ return acc;
249
+ }, []);
250
+ if (!filtered.length) return this;
251
+ const merged = mergeUpdates(filtered);
252
+ return this.applyEncodedState({
253
+ origin,
254
+ update: merged
255
+ });
256
+ }
257
+ canRedo() {
258
+ return !!this.#_undoManager?.canRedo();
259
+ }
260
+ canUndo() {
261
+ return !!this.#_undoManager?.canUndo();
262
+ }
263
+ destroy() {
264
+ this.#_undoManager?.destroy();
265
+ this.value.destroy();
266
+ }
267
+ get(type) {
268
+ if (typeof type === "undefined") return this.#_storage;
269
+ return this.#_storage[type];
270
+ }
271
+ getEncodedState() {
272
+ return fromUint8Array(encodeStateAsUpdate(this.value));
273
+ }
274
+ isEmpty() {
275
+ return !this.value.share.size;
276
+ }
277
+ rebuildStorage(reference) {
278
+ if (!!Object.keys(this.#_storage).length) {
279
+ console.warn("Attempted to rebuild storage multiple times");
280
+ return this;
281
+ }
282
+ this.#_storage = Object.entries(reference).reduce((acc, [key, node]) => {
283
+ /**
284
+ * @description It is important that the XML shared-types be checked before the others
285
+ * because they extend off the non-xml types (thereby you can mistakenly identify the
286
+ * wrong type if checked in the reverse order)
287
+ * @date May 9 ,2025
288
+ */
289
+ if (node instanceof XmlElement) return {
290
+ ...acc,
291
+ [key]: this.value.getXmlElement(key)
292
+ };
293
+ if (node instanceof XmlFragment) return {
294
+ ...acc,
295
+ [key]: this.value.getXmlFragment(key)
296
+ };
297
+ if (node instanceof XmlText) return {
298
+ ...acc,
299
+ [key]: this.value.get(key, XmlText)
300
+ };
301
+ if (node instanceof Array) return {
302
+ ...acc,
303
+ [key]: this.value.getArray(key)
304
+ };
305
+ if (node instanceof Map$1) return {
306
+ ...acc,
307
+ [key]: this.value.getMap(key)
308
+ };
309
+ if (node instanceof Text) return {
310
+ ...acc,
311
+ [key]: this.value.getText(key)
312
+ };
313
+ return acc;
314
+ }, {});
315
+ return this.track();
316
+ }
317
+ redo() {
318
+ this.#_undoManager?.redo();
319
+ return this;
320
+ }
321
+ subscribe(listener) {
322
+ const fn = (update, origin, doc$1) => {
323
+ listener({
324
+ doc: this,
325
+ local: origin === null || typeof origin === "undefined",
326
+ origin: origin ? String(origin) : null,
327
+ update: fromUint8Array(update)
328
+ });
329
+ };
330
+ this.value.on("update", fn);
331
+ return () => {
332
+ this.value.off("update", fn);
333
+ };
334
+ }
335
+ track() {
336
+ if (this.#_undoManager) this.#_undoManager.destroy();
337
+ const sharedTypes = Object.values(this.#_storage).reduce((acc, type) => {
338
+ if (type instanceof Array || type instanceof Map$1 || type instanceof Text || type instanceof XmlElement || type instanceof XmlFragment || type instanceof XmlText) acc.push(type);
339
+ return acc;
340
+ }, []);
341
+ if (!sharedTypes.length) {
342
+ this.#_undoManager?.destroy();
343
+ this.#_undoManager = null;
344
+ return this;
345
+ }
346
+ this.#_undoManager = new UndoManager(sharedTypes, { captureTimeout: MERGE_INTERVAL_MS });
347
+ return this;
348
+ }
349
+ transact(fn) {
350
+ this.value.transact(fn);
351
+ return this;
352
+ }
353
+ toJson(type) {
354
+ if (typeof type === "string") return this.#_storage[type].toJSON();
355
+ return Object.entries(this.#_storage).reduce((acc, [key, value]) => ({
356
+ ...acc,
357
+ [key]: value.toJSON()
358
+ }), {});
359
+ }
360
+ undo() {
361
+ this.#_undoManager?.undo();
362
+ return this;
363
+ }
364
+ #_setPluvId() {
365
+ const text$1 = this.value.getText(PLUV_ID_FIELD);
366
+ const id = typeof crypto !== "undefined" ? crypto.randomUUID() : Math.random().toString();
367
+ text$1.insert(0, id);
368
+ }
415
369
  };
416
370
 
417
- // src/doc/CrdtYjsDocFactory.ts
418
- import { AbstractCrdtDocFactory } from "@pluv/crdt";
419
- var CrdtYjsDocFactory = class _CrdtYjsDocFactory extends AbstractCrdtDocFactory {
420
- constructor(initialStorage = () => ({})) {
421
- super(initialStorage);
422
- this._initialStorage = initialStorage;
423
- }
424
- getEmpty() {
425
- return new CrdtYjsDoc();
426
- }
427
- getFactory(initialStorage) {
428
- return new _CrdtYjsDocFactory(initialStorage != null ? initialStorage : this._initialStorage);
429
- }
430
- getInitialized(initialStorage) {
431
- return new CrdtYjsDoc(initialStorage != null ? initialStorage : this._initialStorage);
432
- }
371
+ //#endregion
372
+ //#region src/doc/CrdtYjsDocFactory.ts
373
+ var CrdtYjsDocFactory = class CrdtYjsDocFactory extends AbstractCrdtDocFactory {
374
+ _initialStorage;
375
+ constructor(initialStorage = () => ({})) {
376
+ super(initialStorage);
377
+ this._initialStorage = initialStorage;
378
+ }
379
+ getEmpty() {
380
+ return new CrdtYjsDoc();
381
+ }
382
+ getFactory(initialStorage) {
383
+ return new CrdtYjsDocFactory(initialStorage ?? this._initialStorage);
384
+ }
385
+ getInitialized(initialStorage) {
386
+ return new CrdtYjsDoc(initialStorage ?? this._initialStorage);
387
+ }
433
388
  };
434
389
 
435
- // src/doc/doc.ts
436
- var doc = (value = () => ({})) => {
437
- return new CrdtYjsDocFactory(value);
390
+ //#endregion
391
+ //#region src/doc/doc.ts
392
+ const doc = (value = () => ({})) => {
393
+ return new CrdtYjsDocFactory(value);
438
394
  };
439
395
 
440
- // src/map/YjsMap.ts
441
- import { Map as YMap3 } from "yjs";
442
- var YjsMap = class extends YMap3 {
443
- constructor(value = []) {
444
- super(value);
445
- this.initialValue = value;
446
- }
447
- __pluvType() {
448
- return {};
449
- }
396
+ //#endregion
397
+ //#region src/map/YjsMap.ts
398
+ var YjsMap = class extends Map$1 {
399
+ initialValue;
400
+ constructor(value = []) {
401
+ super(value);
402
+ this.initialValue = value;
403
+ }
404
+ __pluvType() {
405
+ return {};
406
+ }
450
407
  };
451
408
 
452
- // src/map/map.ts
453
- var map = (value = []) => {
454
- return new YjsMap(value);
409
+ //#endregion
410
+ //#region src/map/map.ts
411
+ const map = (value = []) => {
412
+ return new YjsMap(value);
455
413
  };
456
414
 
457
- // src/provider/PluvYjsProvider.ts
458
- import { StorageState } from "@pluv/types";
459
- import { ObservableV2 as ObservableV22 } from "lib0/observable";
460
- var PluvYjsProvider = class extends ObservableV22 {
461
- constructor(params) {
462
- super();
463
- this._synced = false;
464
- const { presenceField, room } = params;
465
- this.awareness = awareness({ presenceField, room });
466
- this.doc = room.getDoc().value;
467
- this._room = room;
468
- const subscriptions = [
469
- this._room.subscribe.connection(({ storage }) => {
470
- const status = this._toProviderStatus(storage.state);
471
- if (!status) return;
472
- this.emit("status", [{ status }]);
473
- }),
474
- this._room.addEventListener("close", (event) => {
475
- this.emit("connection-close", [event, this]);
476
- }),
477
- this._room.addEventListener("error", (event) => {
478
- this.emit("connection-error", [event, this]);
479
- })
480
- ];
481
- this._unsubscribe = subscriptions.reduce(
482
- (fn, unsubscribe) => () => {
483
- fn();
484
- unsubscribe();
485
- },
486
- () => void 0
487
- );
488
- }
489
- get synced() {
490
- return this._synced;
491
- }
492
- set synced(state) {
493
- if (this._synced === state) return;
494
- this._synced = state;
495
- this.emit("sync", [state]);
496
- this.emit("synced", [state]);
497
- }
498
- destroy() {
499
- this.awareness.destroy();
500
- this._unsubscribe();
501
- super.destroy();
502
- }
503
- _toProviderStatus(state) {
504
- switch (state) {
505
- case StorageState.Loading: {
506
- return "connecting";
507
- }
508
- case StorageState.Unavailable: {
509
- return "disconnected";
510
- }
511
- case StorageState.Offline:
512
- case StorageState.Synced: {
513
- return "connected";
514
- }
515
- default:
516
- return null;
517
- }
518
- }
519
- /**
520
- * !HACK
521
- * @description We dgaf about these, since the room manages these already. We're just mirroring
522
- * the fields that exist in the og provider to make sure everything aligns.
523
- * @see https://github.com/yjs/y-websocket/blob/master/src/y-websocket.js
524
- * @date May 13, 2025
525
- */
526
- connect() {
527
- }
528
- disconnect() {
529
- }
415
+ //#endregion
416
+ //#region src/provider/PluvYjsProvider.ts
417
+ /**
418
+ * !HACK
419
+ * @description This doesn't really do anything but emit states in a Yjs.Provider compatible way.
420
+ * Connections and document syncing are handled by the PluvRoom already.
421
+ * @date May 13, 2025
422
+ */
423
+ var PluvYjsProvider = class extends ObservableV2 {
424
+ awareness;
425
+ doc;
426
+ _room;
427
+ _unsubscribe;
428
+ _synced = false;
429
+ constructor(params) {
430
+ super();
431
+ const { presenceField, room } = params;
432
+ this.awareness = awareness({
433
+ presenceField,
434
+ room
435
+ });
436
+ this.doc = room.getDoc().value;
437
+ this._room = room;
438
+ this._unsubscribe = [
439
+ this._room.subscribe.connection(({ storage }) => {
440
+ const status = this._toProviderStatus(storage.state);
441
+ if (!status) return;
442
+ this.emit("status", [{ status }]);
443
+ }),
444
+ this._room.addEventListener("close", (event) => {
445
+ this.emit("connection-close", [event, this]);
446
+ }),
447
+ this._room.addEventListener("error", (event) => {
448
+ this.emit("connection-error", [event, this]);
449
+ })
450
+ ].reduce((fn, unsubscribe) => () => {
451
+ fn();
452
+ unsubscribe();
453
+ }, () => void 0);
454
+ }
455
+ get synced() {
456
+ return this._synced;
457
+ }
458
+ set synced(state) {
459
+ if (this._synced === state) return;
460
+ this._synced = state;
461
+ this.emit("sync", [state]);
462
+ this.emit("synced", [state]);
463
+ }
464
+ destroy() {
465
+ this.awareness.destroy();
466
+ this._unsubscribe();
467
+ super.destroy();
468
+ }
469
+ _toProviderStatus(state) {
470
+ switch (state) {
471
+ case StorageState.Loading: return "connecting";
472
+ case StorageState.Unavailable: return "disconnected";
473
+ case StorageState.Offline:
474
+ case StorageState.Synced: return "connected";
475
+ default: return null;
476
+ }
477
+ }
478
+ /**
479
+ * !HACK
480
+ * @description We dgaf about these, since the room manages these already. We're just mirroring
481
+ * the fields that exist in the og provider to make sure everything aligns.
482
+ * @see https://github.com/yjs/y-websocket/blob/master/src/y-websocket.js
483
+ * @date May 13, 2025
484
+ */
485
+ connect() {}
486
+ disconnect() {}
530
487
  };
531
488
 
532
- // src/provider/provider.ts
533
- var provider = (params) => {
534
- return new PluvYjsProvider(params);
489
+ //#endregion
490
+ //#region src/provider/provider.ts
491
+ const provider = (params) => {
492
+ return new PluvYjsProvider(params);
535
493
  };
536
494
 
537
- // src/text/YjsText.ts
538
- import { Text as YText3 } from "yjs";
539
- var YjsText = class extends YText3 {
540
- constructor(value = "") {
541
- super();
542
- this.initialValue = value;
543
- }
544
- __pluvType() {
545
- return {};
546
- }
495
+ //#endregion
496
+ //#region src/text/YjsText.ts
497
+ var YjsText = class extends Text {
498
+ initialValue;
499
+ constructor(value = "") {
500
+ super();
501
+ this.initialValue = value;
502
+ }
503
+ __pluvType() {
504
+ return {};
505
+ }
547
506
  };
548
507
 
549
- // src/text/text.ts
550
- var text = (value = "") => {
551
- return new YjsText(value);
508
+ //#endregion
509
+ //#region src/text/text.ts
510
+ const text = (value = "") => {
511
+ return new YjsText(value);
552
512
  };
553
513
 
554
- // src/xmlElement/YjsXmlElement.ts
555
- import { XmlElement as YXmlElement3 } from "yjs";
556
- var YjsXmlElement = class extends YXmlElement3 {
557
- constructor(name, value) {
558
- super(name);
559
- if (!!value.length) this.insert(0, value);
560
- this.initialValue = value;
561
- }
562
- __pluvType() {
563
- return {};
564
- }
514
+ //#endregion
515
+ //#region src/xmlElement/YjsXmlElement.ts
516
+ var YjsXmlElement = class extends XmlElement {
517
+ initialValue;
518
+ constructor(name, value) {
519
+ super(name);
520
+ if (!!value.length) this.insert(0, value);
521
+ this.initialValue = value;
522
+ }
523
+ __pluvType() {
524
+ return {};
525
+ }
565
526
  };
566
527
 
567
- // src/xmlElement/xmlElement.ts
568
- var xmlElement = (name, children) => {
569
- return new YjsXmlElement(name, children);
528
+ //#endregion
529
+ //#region src/xmlElement/xmlElement.ts
530
+ const xmlElement = (name, children) => {
531
+ return new YjsXmlElement(name, children);
570
532
  };
571
533
 
572
- // src/xmlFragment/YjsXmlFragment.ts
573
- import { XmlFragment as YXmlFragment3 } from "yjs";
574
- var YjsXmlFragment = class extends YXmlFragment3 {
575
- constructor(value) {
576
- super();
577
- if (!!value.length) this.insert(0, value);
578
- this.initialValue = value;
579
- }
580
- __pluvType() {
581
- return {};
582
- }
534
+ //#endregion
535
+ //#region src/xmlFragment/YjsXmlFragment.ts
536
+ var YjsXmlFragment = class extends XmlFragment {
537
+ initialValue;
538
+ constructor(value) {
539
+ super();
540
+ if (!!value.length) this.insert(0, value);
541
+ this.initialValue = value;
542
+ }
543
+ __pluvType() {
544
+ return {};
545
+ }
583
546
  };
584
547
 
585
- // src/xmlFragment/xmlFragment.ts
586
- var xmlFragment = (children) => {
587
- return new YjsXmlFragment(children);
548
+ //#endregion
549
+ //#region src/xmlFragment/xmlFragment.ts
550
+ const xmlFragment = (children) => {
551
+ return new YjsXmlFragment(children);
588
552
  };
589
553
 
590
- // src/xmlText/YjsXmlText.ts
591
- import { XmlText as YXmlText3 } from "yjs";
592
- var YjsXmlText = class extends YXmlText3 {
593
- constructor(value = "") {
594
- super();
595
- this.initialValue = value;
596
- }
597
- __pluvType() {
598
- return {};
599
- }
554
+ //#endregion
555
+ //#region src/xmlText/YjsXmlText.ts
556
+ var YjsXmlText = class extends XmlText {
557
+ initialValue;
558
+ constructor(value = "") {
559
+ super();
560
+ this.initialValue = value;
561
+ }
562
+ __pluvType() {
563
+ return {};
564
+ }
600
565
  };
601
566
 
602
- // src/xmlText/xmlText.ts
603
- var xmlText = () => {
604
- return new YjsXmlText();
567
+ //#endregion
568
+ //#region src/xmlText/xmlText.ts
569
+ const xmlText = () => {
570
+ return new YjsXmlText();
605
571
  };
606
572
 
607
- // src/yjs.ts
608
- var kind = "yjs";
609
- export {
610
- yjs_exports as yjs
611
- };
573
+ //#endregion
574
+ //#region src/yjs.ts
575
+ var yjs_exports = /* @__PURE__ */ __exportAll({
576
+ array: () => array,
577
+ awareness: () => awareness,
578
+ doc: () => doc,
579
+ kind: () => kind,
580
+ map: () => map,
581
+ provider: () => provider,
582
+ text: () => text,
583
+ xmlElement: () => xmlElement,
584
+ xmlFragment: () => xmlFragment,
585
+ xmlText: () => xmlText
586
+ });
587
+ const kind = "yjs";
588
+
589
+ //#endregion
590
+ export { yjs_exports as yjs };
591
+ //# sourceMappingURL=index.mjs.map