@y/y 14.0.0-16 → 14.0.0-18
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-DyTeTfmj.js → index-BV-j5wdP.js} +2 -2
- package/dist/{index-R7GxO-36.js.map → index-BV-j5wdP.js.map} +1 -1
- package/dist/{internals.mjs → internals.js} +1 -1
- package/dist/internals.js.map +1 -0
- package/dist/{testHelper.mjs → testHelper.js} +2 -2
- package/dist/testHelper.js.map +1 -0
- package/dist/{yjs.mjs → yjs.js} +2 -2
- package/dist/yjs.js.map +1 -0
- package/package.json +9 -18
- package/dist/Skip-j0kX7pdq.js +0 -12173
- package/dist/Skip-j0kX7pdq.js.map +0 -1
- package/dist/index-DyTeTfmj.js.map +0 -1
- package/dist/index-R7GxO-36.js +0 -165
- package/dist/internals.cjs +0 -286
- package/dist/internals.cjs.map +0 -1
- package/dist/internals.mjs.map +0 -1
- package/dist/testHelper.cjs +0 -780
- package/dist/testHelper.cjs.map +0 -1
- package/dist/testHelper.mjs.map +0 -1
- package/dist/yjs.cjs +0 -151
- package/dist/yjs.cjs.map +0 -1
- package/dist/yjs.mjs.map +0 -1
- package/src/index.js +0 -153
- package/src/internals.js +0 -44
- package/src/structs/AbstractStruct.js +0 -59
- package/src/structs/ContentAny.js +0 -115
- package/src/structs/ContentBinary.js +0 -93
- package/src/structs/ContentDeleted.js +0 -101
- package/src/structs/ContentDoc.js +0 -141
- package/src/structs/ContentEmbed.js +0 -98
- package/src/structs/ContentFormat.js +0 -105
- package/src/structs/ContentJSON.js +0 -119
- package/src/structs/ContentString.js +0 -113
- package/src/structs/ContentType.js +0 -176
- package/src/structs/GC.js +0 -80
- package/src/structs/Item.js +0 -845
- package/src/structs/Skip.js +0 -75
- package/src/types/AbstractType.js +0 -1434
- package/src/types/YArray.js +0 -270
- package/src/types/YMap.js +0 -244
- package/src/types/YText.js +0 -934
- package/src/types/YXmlElement.js +0 -227
- package/src/types/YXmlFragment.js +0 -266
- package/src/types/YXmlHook.js +0 -68
- package/src/types/YXmlText.js +0 -66
- package/src/utils/AbstractConnector.js +0 -25
- package/src/utils/AttributionManager.js +0 -619
- package/src/utils/Doc.js +0 -372
- package/src/utils/EventHandler.js +0 -87
- package/src/utils/ID.js +0 -89
- package/src/utils/IdMap.js +0 -629
- package/src/utils/IdSet.js +0 -823
- package/src/utils/RelativePosition.js +0 -352
- package/src/utils/Snapshot.js +0 -220
- package/src/utils/StructSet.js +0 -137
- package/src/utils/StructStore.js +0 -289
- package/src/utils/Transaction.js +0 -489
- package/src/utils/UndoManager.js +0 -391
- package/src/utils/UpdateDecoder.js +0 -281
- package/src/utils/UpdateEncoder.js +0 -320
- package/src/utils/YEvent.js +0 -216
- package/src/utils/delta-helpers.js +0 -54
- package/src/utils/encoding.js +0 -623
- package/src/utils/isParentOf.js +0 -21
- package/src/utils/logging.js +0 -21
- package/src/utils/types.js +0 -28
- package/src/utils/updates.js +0 -715
- package/tests/testHelper.js +0 -600
package/dist/testHelper.cjs
DELETED
|
@@ -1,780 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var t = require('lib0/testing');
|
|
4
|
-
var prng = require('lib0/prng');
|
|
5
|
-
var encoding = require('lib0/encoding');
|
|
6
|
-
var decoding = require('lib0/decoding');
|
|
7
|
-
var syncProtocol = require('@y/protocols/sync');
|
|
8
|
-
var object = require('lib0/object');
|
|
9
|
-
var map = require('lib0/map');
|
|
10
|
-
var yjs = require('./index-R7GxO-36.js');
|
|
11
|
-
var math = require('lib0/math');
|
|
12
|
-
var list = require('lib0/list');
|
|
13
|
-
var delta = require('lib0/delta');
|
|
14
|
-
var Skip = require('./Skip-j0kX7pdq.js');
|
|
15
|
-
require('lib0/function');
|
|
16
|
-
require('lib0/binary');
|
|
17
|
-
require('lib0/observable');
|
|
18
|
-
require('lib0/array');
|
|
19
|
-
require('lib0/traits');
|
|
20
|
-
require('lib0/random');
|
|
21
|
-
require('lib0/promise');
|
|
22
|
-
require('lib0/buffer');
|
|
23
|
-
require('lib0/error');
|
|
24
|
-
require('lib0/set');
|
|
25
|
-
require('lib0/logging');
|
|
26
|
-
require('lib0/time');
|
|
27
|
-
require('lib0/string');
|
|
28
|
-
require('lib0/hash/rabin');
|
|
29
|
-
require('lib0/iterator');
|
|
30
|
-
require('lib0/environment');
|
|
31
|
-
require('lib0/schema');
|
|
32
|
-
|
|
33
|
-
function _interopNamespaceDefault(e) {
|
|
34
|
-
var n = Object.create(null);
|
|
35
|
-
if (e) {
|
|
36
|
-
Object.keys(e).forEach(function (k) {
|
|
37
|
-
if (k !== 'default') {
|
|
38
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
39
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
40
|
-
enumerable: true,
|
|
41
|
-
get: function () { return e[k]; }
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
n.default = e;
|
|
47
|
-
return Object.freeze(n);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
var t__namespace = /*#__PURE__*/_interopNamespaceDefault(t);
|
|
51
|
-
var prng__namespace = /*#__PURE__*/_interopNamespaceDefault(prng);
|
|
52
|
-
var encoding__namespace = /*#__PURE__*/_interopNamespaceDefault(encoding);
|
|
53
|
-
var decoding__namespace = /*#__PURE__*/_interopNamespaceDefault(decoding);
|
|
54
|
-
var syncProtocol__namespace = /*#__PURE__*/_interopNamespaceDefault(syncProtocol);
|
|
55
|
-
var object__namespace = /*#__PURE__*/_interopNamespaceDefault(object);
|
|
56
|
-
var map__namespace = /*#__PURE__*/_interopNamespaceDefault(map);
|
|
57
|
-
var math__namespace = /*#__PURE__*/_interopNamespaceDefault(math);
|
|
58
|
-
var list__namespace = /*#__PURE__*/_interopNamespaceDefault(list);
|
|
59
|
-
var delta__namespace = /*#__PURE__*/_interopNamespaceDefault(delta);
|
|
60
|
-
|
|
61
|
-
if (typeof window !== 'undefined') {
|
|
62
|
-
// @ts-ignore
|
|
63
|
-
window.Y = yjs.Y; // eslint-disable-line
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* @param {TestYInstance} y // publish message created by `y` to all other online clients
|
|
68
|
-
* @param {Uint8Array} m
|
|
69
|
-
*/
|
|
70
|
-
const broadcastMessage = (y, m) => {
|
|
71
|
-
if (y.tc.onlineConns.has(y)) {
|
|
72
|
-
y.tc.onlineConns.forEach(remoteYInstance => {
|
|
73
|
-
if (remoteYInstance !== y) {
|
|
74
|
-
remoteYInstance._receive(m, y);
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
exports.useV2 = false;
|
|
81
|
-
|
|
82
|
-
const encV1 = {
|
|
83
|
-
encodeStateAsUpdate: Skip.encodeStateAsUpdate,
|
|
84
|
-
mergeUpdates: Skip.mergeUpdates,
|
|
85
|
-
applyUpdate: Skip.applyUpdate,
|
|
86
|
-
logUpdate: Skip.logUpdate,
|
|
87
|
-
updateEventName: /** @type {'update'} */ ('update'),
|
|
88
|
-
diffUpdate: Skip.diffUpdate
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
const encV2 = {
|
|
92
|
-
encodeStateAsUpdate: Skip.encodeStateAsUpdateV2,
|
|
93
|
-
mergeUpdates: Skip.mergeUpdatesV2,
|
|
94
|
-
applyUpdate: Skip.applyUpdateV2,
|
|
95
|
-
logUpdate: Skip.logUpdateV2,
|
|
96
|
-
updateEventName: /** @type {'updateV2'} */ ('updateV2'),
|
|
97
|
-
diffUpdate: Skip.diffUpdateV2
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
exports.enc = encV1;
|
|
101
|
-
|
|
102
|
-
const useV1Encoding = () => {
|
|
103
|
-
exports.useV2 = false;
|
|
104
|
-
exports.enc = encV1;
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
const useV2Encoding = () => {
|
|
108
|
-
console.error('sync protocol doesnt support v2 protocol yet, fallback to v1 encoding'); // @Todo
|
|
109
|
-
exports.useV2 = false;
|
|
110
|
-
exports.enc = encV1;
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
class TestYInstance extends Skip.Doc {
|
|
114
|
-
/**
|
|
115
|
-
* @param {TestConnector} testConnector
|
|
116
|
-
* @param {number} clientID
|
|
117
|
-
*/
|
|
118
|
-
constructor (testConnector, clientID) {
|
|
119
|
-
super();
|
|
120
|
-
this.userID = clientID; // overwriting clientID
|
|
121
|
-
/**
|
|
122
|
-
* @type {TestConnector}
|
|
123
|
-
*/
|
|
124
|
-
this.tc = testConnector;
|
|
125
|
-
/**
|
|
126
|
-
* @type {Map<TestYInstance, Array<Uint8Array>>}
|
|
127
|
-
*/
|
|
128
|
-
this.receiving = new Map();
|
|
129
|
-
testConnector.allConns.add(this);
|
|
130
|
-
/**
|
|
131
|
-
* The list of received updates.
|
|
132
|
-
* We are going to merge them later using Y.mergeUpdates and check if the resulting document is correct.
|
|
133
|
-
* @type {Array<Uint8Array<ArrayBuffer>>}
|
|
134
|
-
*/
|
|
135
|
-
this.updates = [];
|
|
136
|
-
// set up observe on local model
|
|
137
|
-
this.on(exports.enc.updateEventName, (update, origin) => {
|
|
138
|
-
if (origin !== testConnector) {
|
|
139
|
-
const encoder = encoding__namespace.createEncoder();
|
|
140
|
-
syncProtocol__namespace.writeUpdate(encoder, update);
|
|
141
|
-
broadcastMessage(this, encoding__namespace.toUint8Array(encoder));
|
|
142
|
-
}
|
|
143
|
-
this.updates.push(update);
|
|
144
|
-
});
|
|
145
|
-
this.connect();
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Disconnect from TestConnector.
|
|
150
|
-
*/
|
|
151
|
-
disconnect () {
|
|
152
|
-
this.receiving = new Map();
|
|
153
|
-
this.tc.onlineConns.delete(this);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Append yourself to the list of known Y instances in testconnector.
|
|
158
|
-
* Also initiate sync with all clients.
|
|
159
|
-
*/
|
|
160
|
-
connect () {
|
|
161
|
-
if (!this.tc.onlineConns.has(this)) {
|
|
162
|
-
this.tc.onlineConns.add(this);
|
|
163
|
-
const encoder = encoding__namespace.createEncoder();
|
|
164
|
-
syncProtocol__namespace.writeSyncStep1(encoder, this);
|
|
165
|
-
// publish SyncStep1
|
|
166
|
-
broadcastMessage(this, encoding__namespace.toUint8Array(encoder));
|
|
167
|
-
this.tc.onlineConns.forEach(remoteYInstance => {
|
|
168
|
-
if (remoteYInstance !== this) {
|
|
169
|
-
// remote instance sends instance to this instance
|
|
170
|
-
const encoder = encoding__namespace.createEncoder();
|
|
171
|
-
syncProtocol__namespace.writeSyncStep1(encoder, remoteYInstance);
|
|
172
|
-
this._receive(encoding__namespace.toUint8Array(encoder), remoteYInstance);
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Receive a message from another client. This message is only appended to the list of receiving messages.
|
|
180
|
-
* TestConnector decides when this client actually reads this message.
|
|
181
|
-
*
|
|
182
|
-
* @param {Uint8Array} message
|
|
183
|
-
* @param {TestYInstance} remoteClient
|
|
184
|
-
*/
|
|
185
|
-
_receive (message, remoteClient) {
|
|
186
|
-
map__namespace.setIfUndefined(this.receiving, remoteClient, () => /** @type {Array<Uint8Array>} */ ([])).push(message);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Keeps track of TestYInstances.
|
|
192
|
-
*
|
|
193
|
-
* The TestYInstances add/remove themselves from the list of connections maiained in this object.
|
|
194
|
-
* I think it makes sense. Deal with it.
|
|
195
|
-
*/
|
|
196
|
-
class TestConnector {
|
|
197
|
-
/**
|
|
198
|
-
* @param {prng.PRNG} gen
|
|
199
|
-
*/
|
|
200
|
-
constructor (gen) {
|
|
201
|
-
/**
|
|
202
|
-
* @type {Set<TestYInstance>}
|
|
203
|
-
*/
|
|
204
|
-
this.allConns = new Set();
|
|
205
|
-
/**
|
|
206
|
-
* @type {Set<TestYInstance>}
|
|
207
|
-
*/
|
|
208
|
-
this.onlineConns = new Set();
|
|
209
|
-
/**
|
|
210
|
-
* @type {prng.PRNG}
|
|
211
|
-
*/
|
|
212
|
-
this.prng = gen;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Create a new Y instance and add it to the list of connections
|
|
217
|
-
* @param {number} clientID
|
|
218
|
-
*/
|
|
219
|
-
createY (clientID) {
|
|
220
|
-
return new TestYInstance(this, clientID)
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* Choose random connection and flush a random message from a random sender.
|
|
225
|
-
*
|
|
226
|
-
* If this function was unable to flush a message, because there are no more messages to flush, it returns false. true otherwise.
|
|
227
|
-
* @return {boolean}
|
|
228
|
-
*/
|
|
229
|
-
flushRandomMessage () {
|
|
230
|
-
const gen = this.prng;
|
|
231
|
-
const conns = Array.from(this.onlineConns).filter(conn => conn.receiving.size > 0);
|
|
232
|
-
if (conns.length > 0) {
|
|
233
|
-
const receiver = prng__namespace.oneOf(gen, conns);
|
|
234
|
-
const [sender, messages] = prng__namespace.oneOf(gen, Array.from(receiver.receiving));
|
|
235
|
-
const m = messages.shift();
|
|
236
|
-
if (messages.length === 0) {
|
|
237
|
-
receiver.receiving.delete(sender);
|
|
238
|
-
}
|
|
239
|
-
if (m === undefined) {
|
|
240
|
-
return this.flushRandomMessage()
|
|
241
|
-
}
|
|
242
|
-
const encoder = encoding__namespace.createEncoder();
|
|
243
|
-
// console.log('receive (' + sender.userID + '->' + receiver.userID + '):\n', syncProtocol.stringifySyncMessage(decoding.createDecoder(m), receiver))
|
|
244
|
-
// do not publish data created when this function is executed (could be ss2 or update message)
|
|
245
|
-
syncProtocol__namespace.readSyncMessage(decoding__namespace.createDecoder(m), encoder, receiver, receiver.tc);
|
|
246
|
-
if (encoding__namespace.length(encoder) > 0) {
|
|
247
|
-
// send reply message
|
|
248
|
-
sender._receive(encoding__namespace.toUint8Array(encoder), receiver);
|
|
249
|
-
}
|
|
250
|
-
return true
|
|
251
|
-
}
|
|
252
|
-
return false
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* @return {boolean} True iff this function actually flushed something
|
|
257
|
-
*/
|
|
258
|
-
flushAllMessages () {
|
|
259
|
-
let didSomething = false;
|
|
260
|
-
while (this.flushRandomMessage()) {
|
|
261
|
-
didSomething = true;
|
|
262
|
-
}
|
|
263
|
-
return didSomething
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
reconnectAll () {
|
|
267
|
-
this.allConns.forEach(conn => conn.connect());
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
disconnectAll () {
|
|
271
|
-
this.allConns.forEach(conn => conn.disconnect());
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
syncAll () {
|
|
275
|
-
this.reconnectAll();
|
|
276
|
-
this.flushAllMessages();
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* @return {boolean} Whether it was possible to disconnect a random connection.
|
|
281
|
-
*/
|
|
282
|
-
disconnectRandom () {
|
|
283
|
-
if (this.onlineConns.size === 0) {
|
|
284
|
-
return false
|
|
285
|
-
}
|
|
286
|
-
prng__namespace.oneOf(this.prng, Array.from(this.onlineConns)).disconnect();
|
|
287
|
-
return true
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
* @return {boolean} Whether it was possible to reconnect a random connection.
|
|
292
|
-
*/
|
|
293
|
-
reconnectRandom () {
|
|
294
|
-
/**
|
|
295
|
-
* @type {Array<TestYInstance>}
|
|
296
|
-
*/
|
|
297
|
-
const reconnectable = [];
|
|
298
|
-
this.allConns.forEach(conn => {
|
|
299
|
-
if (!this.onlineConns.has(conn)) {
|
|
300
|
-
reconnectable.push(conn);
|
|
301
|
-
}
|
|
302
|
-
});
|
|
303
|
-
if (reconnectable.length === 0) {
|
|
304
|
-
return false
|
|
305
|
-
}
|
|
306
|
-
prng__namespace.oneOf(this.prng, reconnectable).connect();
|
|
307
|
-
return true
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* @template T
|
|
313
|
-
* @param {t.TestCase} tc
|
|
314
|
-
* @param {{users?:number}} conf
|
|
315
|
-
* @param {InitTestObjectCallback<T>} [initTestObject]
|
|
316
|
-
* @return {{testObjects:Array<any>,testConnector:TestConnector,users:Array<TestYInstance>,array0:Y.Array<any>,array1:Y.Array<any>,array2:Y.Array<any>,map0:Y.Map<any>,map1:Y.Map<any>,map2:Y.Map<any>,map3:Y.Map<any>,text0:Y.Text,text1:Y.Text,text2:Y.Text,xml0:Y.XmlElement,xml1:Y.XmlElement,xml2:Y.XmlElement}}
|
|
317
|
-
*/
|
|
318
|
-
const init = (tc, { users = 5 } = {}, initTestObject) => {
|
|
319
|
-
/**
|
|
320
|
-
* @type {Object<string,any>}
|
|
321
|
-
*/
|
|
322
|
-
const result = {
|
|
323
|
-
users: []
|
|
324
|
-
};
|
|
325
|
-
const gen = tc.prng;
|
|
326
|
-
// choose an encoding approach at random
|
|
327
|
-
if (prng__namespace.bool(gen)) {
|
|
328
|
-
useV2Encoding();
|
|
329
|
-
} else {
|
|
330
|
-
useV1Encoding();
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
const testConnector = new TestConnector(gen);
|
|
334
|
-
result.testConnector = testConnector;
|
|
335
|
-
for (let i = 0; i < users; i++) {
|
|
336
|
-
const y = testConnector.createY(i);
|
|
337
|
-
y.clientID = i;
|
|
338
|
-
result.users.push(y);
|
|
339
|
-
result['array' + i] = y.getArray('array');
|
|
340
|
-
result['map' + i] = y.getMap('map');
|
|
341
|
-
result['xml' + i] = y.get('xml', Skip.YXmlElement);
|
|
342
|
-
result['text' + i] = y.getText('text');
|
|
343
|
-
}
|
|
344
|
-
testConnector.syncAll();
|
|
345
|
-
result.testObjects = result.users.map(initTestObject || (() => null));
|
|
346
|
-
useV1Encoding();
|
|
347
|
-
return /** @type {any} */ (result)
|
|
348
|
-
};
|
|
349
|
-
|
|
350
|
-
/**
|
|
351
|
-
* @param {Y.IdSet} idSet1
|
|
352
|
-
* @param {Y.IdSet} idSet2
|
|
353
|
-
*/
|
|
354
|
-
const compareIdSets = (idSet1, idSet2) => {
|
|
355
|
-
t__namespace.assert(idSet1.clients.size === idSet2.clients.size);
|
|
356
|
-
for (const [client, _items1] of idSet1.clients.entries()) {
|
|
357
|
-
const items1 = _items1.getIds();
|
|
358
|
-
const items2 = idSet2.clients.get(client)?.getIds();
|
|
359
|
-
t__namespace.assert(items2 !== undefined && items1.length === items2.length);
|
|
360
|
-
for (let i = 0; i < items1.length; i++) {
|
|
361
|
-
const di1 = items1[i];
|
|
362
|
-
const di2 = /** @type {Array<import('../src/utils/IdSet.js').IdRange>} */ (items2)[i];
|
|
363
|
-
t__namespace.assert(di1.clock === di2.clock && di1.len === di2.len);
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
return true
|
|
367
|
-
};
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* only use for testing
|
|
371
|
-
*
|
|
372
|
-
* @template T
|
|
373
|
-
* @param {Array<Y.Attribution<T>>} attrs
|
|
374
|
-
* @param {Y.Attribution<T>} attr
|
|
375
|
-
*
|
|
376
|
-
*/
|
|
377
|
-
const _idmapAttrsHas = (attrs, attr) => {
|
|
378
|
-
const hash = attr.hash();
|
|
379
|
-
return attrs.find(a => a.hash() === hash)
|
|
380
|
-
};
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* only use for testing
|
|
384
|
-
*
|
|
385
|
-
* @template T
|
|
386
|
-
* @param {Array<Y.Attribution<T>>} a
|
|
387
|
-
* @param {Array<Y.Attribution<T>>} b
|
|
388
|
-
*/
|
|
389
|
-
const _idmapAttrsEqual = (a, b) => a.length === b.length && a.every(v => _idmapAttrsHas(b, v));
|
|
390
|
-
|
|
391
|
-
/**
|
|
392
|
-
* Ensure that all attributes exist. Also create a copy and compare it to the original.
|
|
393
|
-
*
|
|
394
|
-
* @template T
|
|
395
|
-
* @param {Y.IdMap<T>} idmap
|
|
396
|
-
*/
|
|
397
|
-
const validateIdMap = idmap => {
|
|
398
|
-
const copy = Skip.createIdMap();
|
|
399
|
-
idmap.clients.forEach((ranges, client) => {
|
|
400
|
-
ranges.getIds().forEach(range => {
|
|
401
|
-
range.attrs.forEach(attr => {
|
|
402
|
-
t__namespace.assert(idmap.attrs.has(attr));
|
|
403
|
-
t__namespace.assert(idmap.attrsH.get(attr.hash()) === attr);
|
|
404
|
-
copy.add(client, range.clock, range.len, range.attrs.slice());
|
|
405
|
-
});
|
|
406
|
-
});
|
|
407
|
-
t__namespace.assert(copy.clients.get(client)?.getIds().length === ranges.getIds().length);
|
|
408
|
-
});
|
|
409
|
-
t__namespace.assert(idmap.attrsH.size === idmap.attrs.size);
|
|
410
|
-
};
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* @template T
|
|
414
|
-
* @param {Y.IdMap<T>} idmap1
|
|
415
|
-
* @param {Y.IdMap<T>} idmap2
|
|
416
|
-
*/
|
|
417
|
-
const compareIdmaps = (idmap1, idmap2) => {
|
|
418
|
-
t__namespace.assert(idmap1.clients.size === idmap2.clients.size);
|
|
419
|
-
for (const [client, _items1] of idmap1.clients.entries()) {
|
|
420
|
-
const items1 = _items1.getIds();
|
|
421
|
-
const items2 = idmap2.clients.get(client)?.getIds();
|
|
422
|
-
t__namespace.assert(items2 !== undefined && items1.length === items2.length);
|
|
423
|
-
for (let i = 0; i < items1.length; i++) {
|
|
424
|
-
const di1 = items1[i];
|
|
425
|
-
const di2 = /** @type {Array<import('../src/utils/IdMap.js').AttrRange<T>>} */ (items2)[i];
|
|
426
|
-
t__namespace.assert(di1.clock === di2.clock && di1.len === di2.len && _idmapAttrsEqual(di1.attrs, di2.attrs));
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
validateIdMap(idmap1);
|
|
430
|
-
validateIdMap(idmap2);
|
|
431
|
-
};
|
|
432
|
-
|
|
433
|
-
/**
|
|
434
|
-
* @param {prng.PRNG} gen
|
|
435
|
-
* @param {number} clients
|
|
436
|
-
* @param {number} clockRange (max clock - exclusive - by each client)
|
|
437
|
-
*/
|
|
438
|
-
const createRandomIdSet = (gen, clients, clockRange) => {
|
|
439
|
-
const maxOpLen = 5;
|
|
440
|
-
const numOfOps = math__namespace.ceil((clients * clockRange) / maxOpLen);
|
|
441
|
-
const idset = Skip.createIdSet();
|
|
442
|
-
for (let i = 0; i < numOfOps; i++) {
|
|
443
|
-
const client = prng__namespace.uint32(gen, 0, clients - 1);
|
|
444
|
-
const clockStart = prng__namespace.uint32(gen, 0, clockRange);
|
|
445
|
-
const len = prng__namespace.uint32(gen, 0, clockRange - clockStart);
|
|
446
|
-
Skip.addToIdSet(idset, client, clockStart, len);
|
|
447
|
-
}
|
|
448
|
-
if (idset.clients.size === clients && clients > 1 && prng__namespace.bool(gen)) {
|
|
449
|
-
idset.clients.delete(prng__namespace.uint32(gen, 0, clients));
|
|
450
|
-
}
|
|
451
|
-
return idset
|
|
452
|
-
};
|
|
453
|
-
|
|
454
|
-
/**
|
|
455
|
-
* @template T
|
|
456
|
-
* @param {prng.PRNG} gen
|
|
457
|
-
* @param {number} clients
|
|
458
|
-
* @param {number} clockRange (max clock - exclusive - by each client)
|
|
459
|
-
* @param {Array<T>} attrChoices (max clock - exclusive - by each client)
|
|
460
|
-
* @return {Y.IdMap<T>}
|
|
461
|
-
*/
|
|
462
|
-
const createRandomIdMap = (gen, clients, clockRange, attrChoices) => {
|
|
463
|
-
const maxOpLen = 5;
|
|
464
|
-
const numOfOps = math__namespace.ceil((clients * clockRange) / maxOpLen);
|
|
465
|
-
const idMap = Skip.createIdMap();
|
|
466
|
-
for (let i = 0; i < numOfOps; i++) {
|
|
467
|
-
const client = prng__namespace.uint32(gen, 0, clients - 1);
|
|
468
|
-
const clockStart = prng__namespace.uint32(gen, 0, clockRange);
|
|
469
|
-
const len = prng__namespace.uint32(gen, 0, clockRange - clockStart);
|
|
470
|
-
const attrs = [prng__namespace.oneOf(gen, attrChoices)];
|
|
471
|
-
// maybe add another attr
|
|
472
|
-
if (prng__namespace.bool(gen)) {
|
|
473
|
-
const a = prng__namespace.oneOf(gen, attrChoices);
|
|
474
|
-
if (attrs.find(attr => attr === a) == null) {
|
|
475
|
-
attrs.push(a);
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
idMap.add(client, clockStart, len, attrs.map(v => Skip.createAttributionItem('', v)));
|
|
479
|
-
}
|
|
480
|
-
t__namespace.info(`Created IdMap with ${numOfOps} ranges and ${attrChoices.length} different attributes. Encoded size: ${Skip.encodeIdMap(idMap).byteLength}`);
|
|
481
|
-
return idMap
|
|
482
|
-
};
|
|
483
|
-
|
|
484
|
-
/**
|
|
485
|
-
* 1. reconnect and flush all
|
|
486
|
-
* 2. user 0 gc
|
|
487
|
-
* 3. get type content
|
|
488
|
-
* 4. disconnect & reconnect all (so gc is propagated)
|
|
489
|
-
* 5. compare os, ds, ss
|
|
490
|
-
*
|
|
491
|
-
* @param {Array<TestYInstance>} users
|
|
492
|
-
*/
|
|
493
|
-
const compare = users => {
|
|
494
|
-
users.forEach(u => u.connect());
|
|
495
|
-
while (users[0].tc.flushAllMessages()) {} // eslint-disable-line
|
|
496
|
-
// For each document, merge all received document updates with Y.mergeUpdates and create a new document which will be added to the list of "users"
|
|
497
|
-
// This ensures that mergeUpdates works correctly
|
|
498
|
-
const mergedDocs = users.map(user => {
|
|
499
|
-
const ydoc = new Skip.Doc();
|
|
500
|
-
exports.enc.applyUpdate(ydoc, exports.enc.mergeUpdates(user.updates));
|
|
501
|
-
return ydoc
|
|
502
|
-
});
|
|
503
|
-
users.push(.../** @type {any} */(mergedDocs));
|
|
504
|
-
const userArrayValues = users.map(u => u.getArray('array').toJSON());
|
|
505
|
-
const userMapValues = users.map(u => u.getMap('map').toJSON());
|
|
506
|
-
// @todo fix type error here
|
|
507
|
-
// @ts-ignore
|
|
508
|
-
const userXmlValues = users.map(u => /** @type {Y.XmlElement} */ (u.get('xml', Skip.YXmlElement)).toString());
|
|
509
|
-
const userTextValues = users.map(u => u.getText('text').getContentDeep());
|
|
510
|
-
for (const u of users) {
|
|
511
|
-
t__namespace.assert(u.store.pendingDs === null);
|
|
512
|
-
t__namespace.assert(u.store.pendingStructs === null);
|
|
513
|
-
}
|
|
514
|
-
// Test Array iterator
|
|
515
|
-
t__namespace.compare(users[0].getArray('array').toArray(), Array.from(users[0].getArray('array')));
|
|
516
|
-
// Test Map iterator
|
|
517
|
-
const ymapkeys = Array.from(users[0].getMap('map').keys());
|
|
518
|
-
t__namespace.assert(ymapkeys.length === Object.keys(userMapValues[0]).length);
|
|
519
|
-
ymapkeys.forEach(key => t__namespace.assert(object__namespace.hasProperty(userMapValues[0], key)));
|
|
520
|
-
/**
|
|
521
|
-
* @type {Object<string,any>}
|
|
522
|
-
*/
|
|
523
|
-
const mapRes = {};
|
|
524
|
-
for (const [k, v] of users[0].getMap('map')) {
|
|
525
|
-
mapRes[k] = v instanceof Skip.AbstractType ? v.toJSON() : v;
|
|
526
|
-
}
|
|
527
|
-
t__namespace.compare(userMapValues[0], mapRes);
|
|
528
|
-
// Compare all users
|
|
529
|
-
for (let i = 0; i < users.length - 1; i++) {
|
|
530
|
-
t__namespace.compare(userArrayValues[i].length, users[i].getArray('array').length);
|
|
531
|
-
t__namespace.compare(userArrayValues[i], userArrayValues[i + 1]);
|
|
532
|
-
t__namespace.compare(userMapValues[i], userMapValues[i + 1]);
|
|
533
|
-
t__namespace.compare(userXmlValues[i], userXmlValues[i + 1]);
|
|
534
|
-
t__namespace.compare(list__namespace.toArray(userTextValues[i].children).map(a => (delta__namespace.$textOp.check(a) || delta__namespace.$insertOp.check(a)) ? a.insert.length : 0).reduce((a, b) => a + b, 0), users[i].getText('text').length);
|
|
535
|
-
t__namespace.compare(userTextValues[i], userTextValues[i + 1], '', (_constructor, a, b) => {
|
|
536
|
-
if (a instanceof Skip.AbstractType) {
|
|
537
|
-
t__namespace.compare(a.toJSON(), b.toJSON());
|
|
538
|
-
} else if (a !== b) {
|
|
539
|
-
t__namespace.fail('Deltas dont match');
|
|
540
|
-
}
|
|
541
|
-
return true
|
|
542
|
-
});
|
|
543
|
-
t__namespace.compare(Skip.encodeStateVector(users[i]), Skip.encodeStateVector(users[i + 1]));
|
|
544
|
-
Skip.equalIdSets(Skip.createDeleteSetFromStructStore(users[i].store), Skip.createDeleteSetFromStructStore(users[i + 1].store));
|
|
545
|
-
compareStructStores(users[i].store, users[i + 1].store);
|
|
546
|
-
t__namespace.compare(Skip.encodeSnapshot(Skip.snapshot(users[i])), Skip.encodeSnapshot(Skip.snapshot(users[i + 1])));
|
|
547
|
-
}
|
|
548
|
-
users.forEach(user => {
|
|
549
|
-
compareIdSets(user.store.ds, Skip.createDeleteSetFromStructStore(user.store));
|
|
550
|
-
});
|
|
551
|
-
users.map(u => u.destroy());
|
|
552
|
-
};
|
|
553
|
-
|
|
554
|
-
/**
|
|
555
|
-
* @param {Y.Item?} a
|
|
556
|
-
* @param {Y.Item?} b
|
|
557
|
-
* @return {boolean}
|
|
558
|
-
*/
|
|
559
|
-
const compareItemIDs = (a, b) => a === b || (a !== null && b != null && Skip.compareIDs(a.id, b.id));
|
|
560
|
-
|
|
561
|
-
/**
|
|
562
|
-
* @param {import('../src/internals.js').StructStore} ss1
|
|
563
|
-
* @param {import('../src/internals.js').StructStore} ss2
|
|
564
|
-
*/
|
|
565
|
-
const compareStructStores = (ss1, ss2) => {
|
|
566
|
-
t__namespace.assert(ss1.clients.size === ss2.clients.size);
|
|
567
|
-
for (const [client, structs1] of ss1.clients) {
|
|
568
|
-
const structs2 = /** @type {Array<Y.AbstractStruct>} */ (ss2.clients.get(client));
|
|
569
|
-
t__namespace.assert(structs2 !== undefined && structs1.length === structs2.length);
|
|
570
|
-
for (let i = 0; i < structs1.length; i++) {
|
|
571
|
-
const s1 = structs1[i];
|
|
572
|
-
const s2 = structs2[i];
|
|
573
|
-
// checks for abstract struct
|
|
574
|
-
if (
|
|
575
|
-
s1.constructor !== s2.constructor ||
|
|
576
|
-
!Skip.compareIDs(s1.id, s2.id) ||
|
|
577
|
-
s1.deleted !== s2.deleted ||
|
|
578
|
-
// @ts-ignore
|
|
579
|
-
s1.length !== s2.length
|
|
580
|
-
) {
|
|
581
|
-
t__namespace.fail('Structs dont match');
|
|
582
|
-
}
|
|
583
|
-
if (s1 instanceof Skip.Item) {
|
|
584
|
-
if (
|
|
585
|
-
!(s2 instanceof Skip.Item) ||
|
|
586
|
-
!((s1.left === null && s2.left === null) || (s1.left !== null && s2.left !== null && Skip.compareIDs(s1.left.lastId, s2.left.lastId))) ||
|
|
587
|
-
!compareItemIDs(s1.right, s2.right) ||
|
|
588
|
-
!Skip.compareIDs(s1.origin, s2.origin) ||
|
|
589
|
-
!Skip.compareIDs(s1.rightOrigin, s2.rightOrigin) ||
|
|
590
|
-
s1.parentSub !== s2.parentSub
|
|
591
|
-
) {
|
|
592
|
-
return t__namespace.fail('Items dont match')
|
|
593
|
-
}
|
|
594
|
-
// make sure that items are connected correctly
|
|
595
|
-
t__namespace.assert(s1.left === null || s1.left.right === s1);
|
|
596
|
-
t__namespace.assert(s1.right === null || s1.right.left === s1);
|
|
597
|
-
t__namespace.assert(s2.left === null || s2.left.right === s2);
|
|
598
|
-
t__namespace.assert(s2.right === null || s2.right.left === s2);
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
};
|
|
603
|
-
|
|
604
|
-
/**
|
|
605
|
-
* @template T
|
|
606
|
-
* @callback InitTestObjectCallback
|
|
607
|
-
* @param {TestYInstance} y
|
|
608
|
-
* @return {T}
|
|
609
|
-
*/
|
|
610
|
-
|
|
611
|
-
/**
|
|
612
|
-
* @template T
|
|
613
|
-
* @param {t.TestCase} tc
|
|
614
|
-
* @param {Array<function(Y.Doc,prng.PRNG,T):void>} mods
|
|
615
|
-
* @param {number} iterations
|
|
616
|
-
* @param {InitTestObjectCallback<T>} [initTestObject]
|
|
617
|
-
*/
|
|
618
|
-
const applyRandomTests = (tc, mods, iterations, initTestObject) => {
|
|
619
|
-
const gen = tc.prng;
|
|
620
|
-
const result = init(tc, { users: 5 }, initTestObject);
|
|
621
|
-
const { testConnector, users } = result;
|
|
622
|
-
for (let i = 0; i < iterations; i++) {
|
|
623
|
-
if (prng__namespace.int32(gen, 0, 100) <= 2) {
|
|
624
|
-
// 2% chance to disconnect/reconnect a random user
|
|
625
|
-
if (prng__namespace.bool(gen)) {
|
|
626
|
-
testConnector.disconnectRandom();
|
|
627
|
-
} else {
|
|
628
|
-
testConnector.reconnectRandom();
|
|
629
|
-
}
|
|
630
|
-
} else if (prng__namespace.int32(gen, 0, 100) <= 1) {
|
|
631
|
-
// 1% chance to flush all
|
|
632
|
-
testConnector.flushAllMessages();
|
|
633
|
-
} else if (prng__namespace.int32(gen, 0, 100) <= 50) {
|
|
634
|
-
// 50% chance to flush a random message
|
|
635
|
-
testConnector.flushRandomMessage();
|
|
636
|
-
}
|
|
637
|
-
const user = prng__namespace.int32(gen, 0, users.length - 1);
|
|
638
|
-
const test = prng__namespace.oneOf(gen, mods);
|
|
639
|
-
test(users[user], gen, result.testObjects[user]);
|
|
640
|
-
}
|
|
641
|
-
compare(users);
|
|
642
|
-
return result
|
|
643
|
-
};
|
|
644
|
-
|
|
645
|
-
exports.AbsolutePosition = Skip.AbsolutePosition;
|
|
646
|
-
exports.AbstractAttributionManager = Skip.AbstractAttributionManager;
|
|
647
|
-
exports.AbstractConnector = Skip.AbstractConnector;
|
|
648
|
-
exports.AbstractStruct = Skip.AbstractStruct;
|
|
649
|
-
exports.AbstractType = Skip.AbstractType;
|
|
650
|
-
exports.Array = Skip.YArray;
|
|
651
|
-
exports.Attribution = Skip.AttributionItem;
|
|
652
|
-
exports.ContentAny = Skip.ContentAny;
|
|
653
|
-
exports.ContentBinary = Skip.ContentBinary;
|
|
654
|
-
exports.ContentDeleted = Skip.ContentDeleted;
|
|
655
|
-
exports.ContentDoc = Skip.ContentDoc;
|
|
656
|
-
exports.ContentEmbed = Skip.ContentEmbed;
|
|
657
|
-
exports.ContentFormat = Skip.ContentFormat;
|
|
658
|
-
exports.ContentJSON = Skip.ContentJSON;
|
|
659
|
-
exports.ContentString = Skip.ContentString;
|
|
660
|
-
exports.ContentType = Skip.ContentType;
|
|
661
|
-
exports.DiffAttributionManager = Skip.DiffAttributionManager;
|
|
662
|
-
exports.Doc = Skip.Doc;
|
|
663
|
-
exports.GC = Skip.GC;
|
|
664
|
-
exports.ID = Skip.ID;
|
|
665
|
-
exports.IdMap = Skip.IdMap;
|
|
666
|
-
exports.IdSet = Skip.IdSet;
|
|
667
|
-
exports.Item = Skip.Item;
|
|
668
|
-
exports.Map = Skip.YMap;
|
|
669
|
-
exports.RelativePosition = Skip.RelativePosition;
|
|
670
|
-
exports.Skip = Skip.Skip;
|
|
671
|
-
exports.Snapshot = Skip.Snapshot;
|
|
672
|
-
exports.Text = Skip.YText;
|
|
673
|
-
exports.Transaction = Skip.Transaction;
|
|
674
|
-
exports.TwosetAttributionManager = Skip.TwosetAttributionManager;
|
|
675
|
-
exports.UndoManager = Skip.UndoManager;
|
|
676
|
-
exports.UpdateDecoderV1 = Skip.UpdateDecoderV1;
|
|
677
|
-
exports.UpdateDecoderV2 = Skip.UpdateDecoderV2;
|
|
678
|
-
exports.UpdateEncoderV1 = Skip.UpdateEncoderV1;
|
|
679
|
-
exports.UpdateEncoderV2 = Skip.UpdateEncoderV2;
|
|
680
|
-
exports.XmlElement = Skip.YXmlElement;
|
|
681
|
-
exports.XmlFragment = Skip.YXmlFragment;
|
|
682
|
-
exports.XmlHook = Skip.YXmlHook;
|
|
683
|
-
exports.XmlText = Skip.YXmlText;
|
|
684
|
-
exports.YEvent = Skip.YEvent;
|
|
685
|
-
exports.applyUpdate = Skip.applyUpdate;
|
|
686
|
-
exports.applyUpdateV2 = Skip.applyUpdateV2;
|
|
687
|
-
exports.cleanupYTextFormatting = Skip.cleanupYTextFormatting;
|
|
688
|
-
exports.cloneDoc = Skip.cloneDoc;
|
|
689
|
-
exports.compareIDs = Skip.compareIDs;
|
|
690
|
-
exports.compareRelativePositions = Skip.compareRelativePositions;
|
|
691
|
-
exports.convertUpdateFormatV1ToV2 = Skip.convertUpdateFormatV1ToV2;
|
|
692
|
-
exports.convertUpdateFormatV2ToV1 = Skip.convertUpdateFormatV2ToV1;
|
|
693
|
-
exports.createAbsolutePositionFromRelativePosition = Skip.createAbsolutePositionFromRelativePosition;
|
|
694
|
-
exports.createAttributionItem = Skip.createAttributionItem;
|
|
695
|
-
exports.createAttributionManagerFromDiff = Skip.createAttributionManagerFromDiff;
|
|
696
|
-
exports.createDeleteSetFromStructStore = Skip.createDeleteSetFromStructStore;
|
|
697
|
-
exports.createDocFromSnapshot = Skip.createDocFromSnapshot;
|
|
698
|
-
exports.createID = Skip.createID;
|
|
699
|
-
exports.createIdMap = Skip.createIdMap;
|
|
700
|
-
exports.createIdMapFromIdSet = Skip.createIdMapFromIdSet;
|
|
701
|
-
exports.createIdSet = Skip.createIdSet;
|
|
702
|
-
exports.createInsertionSetFromStructStore = Skip.createInsertSetFromStructStore;
|
|
703
|
-
exports.createRelativePositionFromJSON = Skip.createRelativePositionFromJSON;
|
|
704
|
-
exports.createRelativePositionFromTypeIndex = Skip.createRelativePositionFromTypeIndex;
|
|
705
|
-
exports.createSnapshot = Skip.createSnapshot;
|
|
706
|
-
exports.decodeIdMap = Skip.decodeIdMap;
|
|
707
|
-
exports.decodeRelativePosition = Skip.decodeRelativePosition;
|
|
708
|
-
exports.decodeSnapshot = Skip.decodeSnapshot;
|
|
709
|
-
exports.decodeSnapshotV2 = Skip.decodeSnapshotV2;
|
|
710
|
-
exports.decodeStateVector = Skip.decodeStateVector;
|
|
711
|
-
exports.decodeUpdate = Skip.decodeUpdate;
|
|
712
|
-
exports.decodeUpdateV2 = Skip.decodeUpdateV2;
|
|
713
|
-
exports.diffDocsToDelta = Skip.diffDocsToDelta;
|
|
714
|
-
exports.diffIdMap = Skip.diffIdMap;
|
|
715
|
-
exports.diffIdSet = Skip.diffIdSet;
|
|
716
|
-
exports.diffUpdate = Skip.diffUpdate;
|
|
717
|
-
exports.diffUpdateV2 = Skip.diffUpdateV2;
|
|
718
|
-
exports.emptySnapshot = Skip.emptySnapshot;
|
|
719
|
-
exports.encodeIdMap = Skip.encodeIdMap;
|
|
720
|
-
exports.encodeRelativePosition = Skip.encodeRelativePosition;
|
|
721
|
-
exports.encodeSnapshot = Skip.encodeSnapshot;
|
|
722
|
-
exports.encodeSnapshotV2 = Skip.encodeSnapshotV2;
|
|
723
|
-
exports.encodeStateAsUpdate = Skip.encodeStateAsUpdate;
|
|
724
|
-
exports.encodeStateAsUpdateV2 = Skip.encodeStateAsUpdateV2;
|
|
725
|
-
exports.encodeStateVector = Skip.encodeStateVector;
|
|
726
|
-
exports.encodeStateVectorFromUpdate = Skip.encodeStateVectorFromUpdate;
|
|
727
|
-
exports.encodeStateVectorFromUpdateV2 = Skip.encodeStateVectorFromUpdateV2;
|
|
728
|
-
exports.equalIdSets = Skip.equalIdSets;
|
|
729
|
-
exports.equalSnapshots = Skip.equalSnapshots;
|
|
730
|
-
exports.findIndexSS = Skip.findIndexSS;
|
|
731
|
-
exports.findRootTypeKey = Skip.findRootTypeKey;
|
|
732
|
-
exports.getItem = Skip.getItem;
|
|
733
|
-
exports.getItemCleanEnd = Skip.getItemCleanEnd;
|
|
734
|
-
exports.getItemCleanStart = Skip.getItemCleanStart;
|
|
735
|
-
exports.getState = Skip.getState;
|
|
736
|
-
exports.getTypeChildren = Skip.getTypeChildren;
|
|
737
|
-
exports.insertIntoIdMap = Skip.insertIntoIdMap;
|
|
738
|
-
exports.insertIntoIdSet = Skip.insertIntoIdSet;
|
|
739
|
-
exports.isParentOf = Skip.isParentOf;
|
|
740
|
-
exports.iterateStructsByIdSet = Skip.iterateStructsByIdSet;
|
|
741
|
-
exports.logType = Skip.logType;
|
|
742
|
-
exports.logUpdate = Skip.logUpdate;
|
|
743
|
-
exports.logUpdateV2 = Skip.logUpdateV2;
|
|
744
|
-
exports.mergeIdMaps = Skip.mergeIdMaps;
|
|
745
|
-
exports.mergeIdSets = Skip.mergeIdSets;
|
|
746
|
-
exports.mergeUpdates = Skip.mergeUpdates;
|
|
747
|
-
exports.mergeUpdatesV2 = Skip.mergeUpdatesV2;
|
|
748
|
-
exports.noAttributionsManager = Skip.noAttributionsManager;
|
|
749
|
-
exports.obfuscateUpdate = Skip.obfuscateUpdate;
|
|
750
|
-
exports.obfuscateUpdateV2 = Skip.obfuscateUpdateV2;
|
|
751
|
-
exports.readIdMap = Skip.readIdMap;
|
|
752
|
-
exports.readIdSet = Skip.readIdSet;
|
|
753
|
-
exports.readUpdate = Skip.readUpdate;
|
|
754
|
-
exports.readUpdateIdRanges = Skip.readUpdateIdRanges;
|
|
755
|
-
exports.readUpdateIdRangesV2 = Skip.readUpdateIdRangesV2;
|
|
756
|
-
exports.readUpdateV2 = Skip.readUpdateV2;
|
|
757
|
-
exports.relativePositionToJSON = Skip.relativePositionToJSON;
|
|
758
|
-
exports.snapshot = Skip.snapshot;
|
|
759
|
-
exports.snapshotContainsUpdate = Skip.snapshotContainsUpdate;
|
|
760
|
-
exports.transact = Skip.transact;
|
|
761
|
-
exports.tryGc = Skip.tryGc;
|
|
762
|
-
exports.typeListToArraySnapshot = Skip.typeListToArraySnapshot;
|
|
763
|
-
exports.typeMapGetAllSnapshot = Skip.typeMapGetAllSnapshot;
|
|
764
|
-
exports.typeMapGetSnapshot = Skip.typeMapGetSnapshot;
|
|
765
|
-
exports.TestConnector = TestConnector;
|
|
766
|
-
exports.TestYInstance = TestYInstance;
|
|
767
|
-
exports._idmapAttrsEqual = _idmapAttrsEqual;
|
|
768
|
-
exports.applyRandomTests = applyRandomTests;
|
|
769
|
-
exports.compare = compare;
|
|
770
|
-
exports.compareIdSets = compareIdSets;
|
|
771
|
-
exports.compareIdmaps = compareIdmaps;
|
|
772
|
-
exports.compareItemIDs = compareItemIDs;
|
|
773
|
-
exports.compareStructStores = compareStructStores;
|
|
774
|
-
exports.createRandomIdMap = createRandomIdMap;
|
|
775
|
-
exports.createRandomIdSet = createRandomIdSet;
|
|
776
|
-
exports.encV1 = encV1;
|
|
777
|
-
exports.encV2 = encV2;
|
|
778
|
-
exports.init = init;
|
|
779
|
-
exports.validateIdMap = validateIdMap;
|
|
780
|
-
//# sourceMappingURL=testHelper.cjs.map
|