@liveblocks/yjs 1.0.12-yjs3 → 1.1.0-yjs1

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.
Files changed (2) hide show
  1. package/dist/index.mjs +267 -0
  2. package/package.json +11 -4
package/dist/index.mjs ADDED
@@ -0,0 +1,267 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
4
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __spreadValues = (a, b) => {
7
+ for (var prop in b || (b = {}))
8
+ if (__hasOwnProp.call(b, prop))
9
+ __defNormalProp(a, prop, b[prop]);
10
+ if (__getOwnPropSymbols)
11
+ for (var prop of __getOwnPropSymbols(b)) {
12
+ if (__propIsEnum.call(b, prop))
13
+ __defNormalProp(a, prop, b[prop]);
14
+ }
15
+ return a;
16
+ };
17
+ var __async = (__this, __arguments, generator) => {
18
+ return new Promise((resolve, reject) => {
19
+ var fulfilled = (value) => {
20
+ try {
21
+ step(generator.next(value));
22
+ } catch (e) {
23
+ reject(e);
24
+ }
25
+ };
26
+ var rejected = (value) => {
27
+ try {
28
+ step(generator.throw(value));
29
+ } catch (e) {
30
+ reject(e);
31
+ }
32
+ };
33
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
34
+ step((generator = generator.apply(__this, __arguments)).next());
35
+ });
36
+ };
37
+
38
+ // src/index.ts
39
+ import { Base64 } from "js-base64";
40
+
41
+ // ../../node_modules/lib0/map.js
42
+ var create = () => /* @__PURE__ */ new Map();
43
+ var setIfUndefined = (map, key, createT) => {
44
+ let set = map.get(key);
45
+ if (set === void 0) {
46
+ map.set(key, set = createT());
47
+ }
48
+ return set;
49
+ };
50
+
51
+ // ../../node_modules/lib0/set.js
52
+ var create2 = () => /* @__PURE__ */ new Set();
53
+
54
+ // ../../node_modules/lib0/array.js
55
+ var from = Array.from;
56
+ var isArray = Array.isArray;
57
+
58
+ // ../../node_modules/lib0/observable.js
59
+ var Observable = class {
60
+ constructor() {
61
+ this._observers = create();
62
+ }
63
+ /**
64
+ * @param {N} name
65
+ * @param {function} f
66
+ */
67
+ on(name, f) {
68
+ setIfUndefined(this._observers, name, create2).add(f);
69
+ }
70
+ /**
71
+ * @param {N} name
72
+ * @param {function} f
73
+ */
74
+ once(name, f) {
75
+ const _f = (...args) => {
76
+ this.off(name, _f);
77
+ f(...args);
78
+ };
79
+ this.on(name, _f);
80
+ }
81
+ /**
82
+ * @param {N} name
83
+ * @param {function} f
84
+ */
85
+ off(name, f) {
86
+ const observers = this._observers.get(name);
87
+ if (observers !== void 0) {
88
+ observers.delete(f);
89
+ if (observers.size === 0) {
90
+ this._observers.delete(name);
91
+ }
92
+ }
93
+ }
94
+ /**
95
+ * Emit a named event. All registered event listeners that listen to the
96
+ * specified name will receive the event.
97
+ *
98
+ * @todo This should catch exceptions
99
+ *
100
+ * @param {N} name The event name.
101
+ * @param {Array<any>} args The arguments that are applied to the event listener.
102
+ */
103
+ emit(name, args) {
104
+ return from((this._observers.get(name) || create()).values()).forEach((f) => f(...args));
105
+ }
106
+ destroy() {
107
+ this._observers = create();
108
+ }
109
+ };
110
+
111
+ // src/index.ts
112
+ import * as Y from "yjs";
113
+ var Awareness = class extends Observable {
114
+ constructor(doc, room) {
115
+ super();
116
+ this.states = /* @__PURE__ */ new Map();
117
+ // Meta is used to keep track and timeout users who disconnect. Liveblocks provides this for us, so we don't need to
118
+ // manage it here. Unfortunately, it's expected to exist by various integrations, so it's an empty map.
119
+ this.meta = /* @__PURE__ */ new Map();
120
+ // _checkInterval this would hold a timer to remove users, but Liveblock's presence already handles this
121
+ // unfortunately it's expected to exist by various integrations.
122
+ this._checkInterval = 0;
123
+ this.doc = doc;
124
+ this.room = room;
125
+ this.clientID = doc.clientID;
126
+ this.othersUnsub = this.room.events.others.subscribe(({ event }) => {
127
+ if (event.type === "leave") {
128
+ this.emit("change", [
129
+ { added: [], updated: [], removed: [event.user.connectionId] },
130
+ "local"
131
+ ]);
132
+ }
133
+ if (event.type === "enter") {
134
+ this.emit("change", [
135
+ { added: [event.user.connectionId], updated: [], removed: [] },
136
+ "local"
137
+ ]);
138
+ }
139
+ if (event.type === "update") {
140
+ this.emit("change", [
141
+ { added: [], updated: [event.user.connectionId], removed: [] },
142
+ "local"
143
+ ]);
144
+ }
145
+ });
146
+ }
147
+ destroy() {
148
+ this.emit("destroy", [this]);
149
+ this.othersUnsub();
150
+ this.setLocalState(null);
151
+ super.destroy();
152
+ }
153
+ getLocalState() {
154
+ const presence = this.room.getPresence();
155
+ if (Object.keys(this.room.getPresence()).length === 0) {
156
+ return null;
157
+ }
158
+ return presence["__yjs"];
159
+ }
160
+ setLocalState(state) {
161
+ const self = this.room.getSelf();
162
+ if (!self) {
163
+ return;
164
+ }
165
+ this.room.updatePresence({ __yjs: __spreadValues({}, state || {}) });
166
+ }
167
+ setLocalStateField(field, value) {
168
+ const update = { [field]: value };
169
+ this.room.updatePresence({ __yjs: update });
170
+ }
171
+ // Translate
172
+ getStates() {
173
+ const others = this.room.getOthers();
174
+ const states = others.reduce((acc, currentValue) => {
175
+ if (currentValue.connectionId) {
176
+ acc.set(currentValue.connectionId, currentValue.presence["__yjs"]);
177
+ }
178
+ return acc;
179
+ }, /* @__PURE__ */ new Map());
180
+ return states;
181
+ }
182
+ };
183
+ var LiveblocksProvider = class {
184
+ constructor(room, doc, config) {
185
+ this.lastUpdateDate = null;
186
+ this.unsubscribers = [];
187
+ this.updateHandler = (update, origin) => __async(this, null, function* () {
188
+ if (origin !== "backend") {
189
+ const encodedUpdate = Base64.fromUint8Array(update);
190
+ this.room.updateDoc(encodedUpdate);
191
+ if (this.httpEndpoint) {
192
+ yield fetch(this.httpEndpoint, {
193
+ method: "POST",
194
+ body: encodedUpdate
195
+ });
196
+ }
197
+ }
198
+ });
199
+ var _a;
200
+ this.doc = doc;
201
+ this.room = room;
202
+ const connectionId = (_a = this.room.getSelf()) == null ? void 0 : _a.connectionId;
203
+ if (connectionId) {
204
+ this.doc.clientID = connectionId;
205
+ }
206
+ this.awareness = new Awareness(this.doc, this.room);
207
+ this.doc.on("update", this.updateHandler);
208
+ this.unsubscribers.push(
209
+ this.room.events.connection.subscribe((e) => {
210
+ var _a2;
211
+ if (e === "open") {
212
+ this.doc.clientID = ((_a2 = this.room.getSelf()) == null ? void 0 : _a2.connectionId) || this.doc.clientID;
213
+ this.awareness.clientID = this.doc.clientID;
214
+ const encodedVector = Base64.fromUint8Array(
215
+ Y.encodeStateVector(this.doc)
216
+ );
217
+ this.room.getDoc(encodedVector);
218
+ }
219
+ })
220
+ );
221
+ this.unsubscribers.push(
222
+ this.room.events.docUpdated.subscribe((updates) => {
223
+ const decodedUpdates = updates.map(Base64.toUint8Array);
224
+ const update = Y.mergeUpdates(decodedUpdates);
225
+ Y.applyUpdate(this.doc, update, "backend");
226
+ })
227
+ );
228
+ if (config == null ? void 0 : config.httpEndpoint) {
229
+ this.httpEndpoint = config.httpEndpoint + "?room=" + this.room.id;
230
+ this.unsubscribers.push(
231
+ this.room.events.customEvent.subscribe(({ event }) => {
232
+ if ((event == null ? void 0 : event.type) === "REFRESH") {
233
+ void this.resyncHttp();
234
+ }
235
+ })
236
+ );
237
+ void this.resyncHttp();
238
+ }
239
+ this.room.getDoc();
240
+ }
241
+ resyncHttp() {
242
+ return __async(this, null, function* () {
243
+ if (!this.httpEndpoint) {
244
+ return;
245
+ }
246
+ const response = yield fetch(
247
+ `${this.httpEndpoint}${this.lastUpdateDate !== null ? `&after=${this.lastUpdateDate.toISOString()}` : ""}`
248
+ );
249
+ const { updates, lastUpdate } = yield response.json();
250
+ if (updates.length === 0) {
251
+ return;
252
+ }
253
+ this.lastUpdateDate = new Date(lastUpdate);
254
+ const update = Y.mergeUpdates(updates.map(Base64.toUint8Array));
255
+ Y.applyUpdate(this.doc, update, "backend");
256
+ });
257
+ }
258
+ destroy() {
259
+ this.doc.off("update", this.updateHandler);
260
+ this.unsubscribers.forEach((unsub) => unsub());
261
+ this.awareness.destroy();
262
+ }
263
+ };
264
+ export {
265
+ Awareness,
266
+ LiveblocksProvider as default
267
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liveblocks/yjs",
3
- "version": "1.0.12-yjs3",
3
+ "version": "1.1.0-yjs1",
4
4
  "description": "An integration with . Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.",
5
5
  "license": "Apache-2.0",
6
6
  "main": "./dist/index.js",
@@ -11,16 +11,23 @@
11
11
  ],
12
12
  "scripts": {
13
13
  "dev": "tsup --watch",
14
- "build": "tsup",
14
+ "build": "tsup --format cjs,esm --dts --clean",
15
15
  "format": "eslint --fix src/; prettier --write src/",
16
16
  "lint": "eslint src/",
17
17
  "test": "jest --silent --verbose --color=always",
18
18
  "test:types": "tsd",
19
19
  "test:watch": "jest --silent --verbose --color=always --watch"
20
20
  },
21
+ "exports": {
22
+ ".": {
23
+ "require": "./dist/index.js",
24
+ "import": "./dist/index.mjs",
25
+ "types": "./dist/index.d.ts"
26
+ }
27
+ },
21
28
  "dependencies": {
22
- "@liveblocks/client": "1.0.12-yjs3",
23
- "@liveblocks/core": "1.0.12-yjs3",
29
+ "@liveblocks/client": "1.1.0-yjs1",
30
+ "@liveblocks/core": "1.1.0-yjs1",
24
31
  "js-base64": "^3.7.5"
25
32
  },
26
33
  "peerDependencies": {