@y/y 14.0.0-16

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 (193) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +1406 -0
  3. package/dist/Skip-j0kX7pdq.js +12173 -0
  4. package/dist/Skip-j0kX7pdq.js.map +1 -0
  5. package/dist/Skip-wRT7BKFP.js +11877 -0
  6. package/dist/Skip-wRT7BKFP.js.map +1 -0
  7. package/dist/index-DyTeTfmj.js +163 -0
  8. package/dist/index-DyTeTfmj.js.map +1 -0
  9. package/dist/index-R7GxO-36.js +165 -0
  10. package/dist/index-R7GxO-36.js.map +1 -0
  11. package/dist/internals.cjs +286 -0
  12. package/dist/internals.cjs.map +1 -0
  13. package/dist/internals.mjs +25 -0
  14. package/dist/internals.mjs.map +1 -0
  15. package/dist/src/index.d.ts +2 -0
  16. package/dist/src/index.d.ts.map +1 -0
  17. package/dist/src/internals.d.ts +43 -0
  18. package/dist/src/internals.d.ts.map +1 -0
  19. package/dist/src/structs/AbstractStruct.d.ts +42 -0
  20. package/dist/src/structs/AbstractStruct.d.ts.map +1 -0
  21. package/dist/src/structs/ContentAny.d.ts +67 -0
  22. package/dist/src/structs/ContentAny.d.ts.map +1 -0
  23. package/dist/src/structs/ContentBinary.d.ts +64 -0
  24. package/dist/src/structs/ContentBinary.d.ts.map +1 -0
  25. package/dist/src/structs/ContentDeleted.d.ts +64 -0
  26. package/dist/src/structs/ContentDeleted.d.ts.map +1 -0
  27. package/dist/src/structs/ContentDoc.d.ts +72 -0
  28. package/dist/src/structs/ContentDoc.d.ts.map +1 -0
  29. package/dist/src/structs/ContentEmbed.d.ts +67 -0
  30. package/dist/src/structs/ContentEmbed.d.ts.map +1 -0
  31. package/dist/src/structs/ContentFormat.d.ts +69 -0
  32. package/dist/src/structs/ContentFormat.d.ts.map +1 -0
  33. package/dist/src/structs/ContentJSON.d.ts +70 -0
  34. package/dist/src/structs/ContentJSON.d.ts.map +1 -0
  35. package/dist/src/structs/ContentString.d.ts +70 -0
  36. package/dist/src/structs/ContentString.d.ts.map +1 -0
  37. package/dist/src/structs/ContentType.d.ts +83 -0
  38. package/dist/src/structs/ContentType.d.ts.map +1 -0
  39. package/dist/src/structs/GC.d.ts +31 -0
  40. package/dist/src/structs/GC.d.ts.map +1 -0
  41. package/dist/src/structs/Item.d.ts +212 -0
  42. package/dist/src/structs/Item.d.ts.map +1 -0
  43. package/dist/src/structs/Skip.d.ts +33 -0
  44. package/dist/src/structs/Skip.d.ts.map +1 -0
  45. package/dist/src/types/AbstractType.d.ts +239 -0
  46. package/dist/src/types/AbstractType.d.ts.map +1 -0
  47. package/dist/src/types/YArray.d.ts +128 -0
  48. package/dist/src/types/YArray.d.ts.map +1 -0
  49. package/dist/src/types/YMap.d.ts +112 -0
  50. package/dist/src/types/YMap.d.ts.map +1 -0
  51. package/dist/src/types/YText.d.ts +216 -0
  52. package/dist/src/types/YText.d.ts.map +1 -0
  53. package/dist/src/types/YXmlElement.d.ts +106 -0
  54. package/dist/src/types/YXmlElement.d.ts.map +1 -0
  55. package/dist/src/types/YXmlFragment.d.ts +143 -0
  56. package/dist/src/types/YXmlFragment.d.ts.map +1 -0
  57. package/dist/src/types/YXmlHook.d.ts +32 -0
  58. package/dist/src/types/YXmlHook.d.ts.map +1 -0
  59. package/dist/src/types/YXmlText.d.ts +34 -0
  60. package/dist/src/types/YXmlText.d.ts.map +1 -0
  61. package/dist/src/utils/AbstractConnector.d.ts +20 -0
  62. package/dist/src/utils/AbstractConnector.d.ts.map +1 -0
  63. package/dist/src/utils/AttributionManager.d.ts +224 -0
  64. package/dist/src/utils/AttributionManager.d.ts.map +1 -0
  65. package/dist/src/utils/Doc.d.ts +267 -0
  66. package/dist/src/utils/Doc.d.ts.map +1 -0
  67. package/dist/src/utils/EventHandler.d.ts +19 -0
  68. package/dist/src/utils/EventHandler.d.ts.map +1 -0
  69. package/dist/src/utils/ID.d.ts +26 -0
  70. package/dist/src/utils/ID.d.ts.map +1 -0
  71. package/dist/src/utils/IdMap.d.ts +161 -0
  72. package/dist/src/utils/IdMap.d.ts.map +1 -0
  73. package/dist/src/utils/IdSet.d.ts +163 -0
  74. package/dist/src/utils/IdSet.d.ts.map +1 -0
  75. package/dist/src/utils/RelativePosition.d.ts +91 -0
  76. package/dist/src/utils/RelativePosition.d.ts.map +1 -0
  77. package/dist/src/utils/Snapshot.d.ts +40 -0
  78. package/dist/src/utils/Snapshot.d.ts.map +1 -0
  79. package/dist/src/utils/StructSet.d.ts +27 -0
  80. package/dist/src/utils/StructSet.d.ts.map +1 -0
  81. package/dist/src/utils/StructStore.d.ts +41 -0
  82. package/dist/src/utils/StructStore.d.ts.map +1 -0
  83. package/dist/src/utils/Transaction.d.ts +136 -0
  84. package/dist/src/utils/Transaction.d.ts.map +1 -0
  85. package/dist/src/utils/UndoManager.d.ts +188 -0
  86. package/dist/src/utils/UndoManager.d.ts.map +1 -0
  87. package/dist/src/utils/UpdateDecoder.d.ts +167 -0
  88. package/dist/src/utils/UpdateDecoder.d.ts.map +1 -0
  89. package/dist/src/utils/UpdateEncoder.d.ts +164 -0
  90. package/dist/src/utils/UpdateEncoder.d.ts.map +1 -0
  91. package/dist/src/utils/YEvent.d.ts +120 -0
  92. package/dist/src/utils/YEvent.d.ts.map +1 -0
  93. package/dist/src/utils/delta-helpers.d.ts +6 -0
  94. package/dist/src/utils/delta-helpers.d.ts.map +1 -0
  95. package/dist/src/utils/encoding.d.ts +30 -0
  96. package/dist/src/utils/encoding.d.ts.map +1 -0
  97. package/dist/src/utils/isParentOf.d.ts +3 -0
  98. package/dist/src/utils/isParentOf.d.ts.map +1 -0
  99. package/dist/src/utils/logging.d.ts +3 -0
  100. package/dist/src/utils/logging.d.ts.map +1 -0
  101. package/dist/src/utils/types.d.ts +7 -0
  102. package/dist/src/utils/types.d.ts.map +1 -0
  103. package/dist/src/utils/updates.d.ts +89 -0
  104. package/dist/src/utils/updates.d.ts.map +1 -0
  105. package/dist/testHelper.cjs +780 -0
  106. package/dist/testHelper.cjs.map +1 -0
  107. package/dist/testHelper.mjs +617 -0
  108. package/dist/testHelper.mjs.map +1 -0
  109. package/dist/tests/IdMap.tests.d.ts +9 -0
  110. package/dist/tests/IdMap.tests.d.ts.map +1 -0
  111. package/dist/tests/IdSet.tests.d.ts +9 -0
  112. package/dist/tests/IdSet.tests.d.ts.map +1 -0
  113. package/dist/tests/attribution.tests.d.ts +8 -0
  114. package/dist/tests/attribution.tests.d.ts.map +1 -0
  115. package/dist/tests/compatibility.tests.d.ts +5 -0
  116. package/dist/tests/compatibility.tests.d.ts.map +1 -0
  117. package/dist/tests/delta.tests.d.ts +7 -0
  118. package/dist/tests/delta.tests.d.ts.map +1 -0
  119. package/dist/tests/doc.tests.d.ts +13 -0
  120. package/dist/tests/doc.tests.d.ts.map +1 -0
  121. package/dist/tests/encoding.tests.d.ts +5 -0
  122. package/dist/tests/encoding.tests.d.ts.map +1 -0
  123. package/dist/tests/index.d.ts +2 -0
  124. package/dist/tests/index.d.ts.map +1 -0
  125. package/dist/tests/relativePositions.tests.d.ts +11 -0
  126. package/dist/tests/relativePositions.tests.d.ts.map +1 -0
  127. package/dist/tests/snapshot.tests.d.ts +13 -0
  128. package/dist/tests/snapshot.tests.d.ts.map +1 -0
  129. package/dist/tests/testHelper.d.ts +167 -0
  130. package/dist/tests/testHelper.d.ts.map +1 -0
  131. package/dist/tests/undo-redo.tests.d.ts +27 -0
  132. package/dist/tests/undo-redo.tests.d.ts.map +1 -0
  133. package/dist/tests/updates.tests.d.ts +24 -0
  134. package/dist/tests/updates.tests.d.ts.map +1 -0
  135. package/dist/tests/y-array.tests.d.ts +45 -0
  136. package/dist/tests/y-array.tests.d.ts.map +1 -0
  137. package/dist/tests/y-map.tests.d.ts +45 -0
  138. package/dist/tests/y-map.tests.d.ts.map +1 -0
  139. package/dist/tests/y-text.tests.d.ts +49 -0
  140. package/dist/tests/y-text.tests.d.ts.map +1 -0
  141. package/dist/tests/y-xml.tests.d.ts +15 -0
  142. package/dist/tests/y-xml.tests.d.ts.map +1 -0
  143. package/dist/yjs.cjs +151 -0
  144. package/dist/yjs.cjs.map +1 -0
  145. package/dist/yjs.mjs +26 -0
  146. package/dist/yjs.mjs.map +1 -0
  147. package/package.json +101 -0
  148. package/src/index.js +153 -0
  149. package/src/internals.js +44 -0
  150. package/src/structs/AbstractStruct.js +59 -0
  151. package/src/structs/ContentAny.js +115 -0
  152. package/src/structs/ContentBinary.js +93 -0
  153. package/src/structs/ContentDeleted.js +101 -0
  154. package/src/structs/ContentDoc.js +141 -0
  155. package/src/structs/ContentEmbed.js +98 -0
  156. package/src/structs/ContentFormat.js +105 -0
  157. package/src/structs/ContentJSON.js +119 -0
  158. package/src/structs/ContentString.js +113 -0
  159. package/src/structs/ContentType.js +176 -0
  160. package/src/structs/GC.js +80 -0
  161. package/src/structs/Item.js +845 -0
  162. package/src/structs/Skip.js +75 -0
  163. package/src/types/AbstractType.js +1434 -0
  164. package/src/types/YArray.js +270 -0
  165. package/src/types/YMap.js +244 -0
  166. package/src/types/YText.js +934 -0
  167. package/src/types/YXmlElement.js +227 -0
  168. package/src/types/YXmlFragment.js +266 -0
  169. package/src/types/YXmlHook.js +68 -0
  170. package/src/types/YXmlText.js +66 -0
  171. package/src/utils/AbstractConnector.js +25 -0
  172. package/src/utils/AttributionManager.js +619 -0
  173. package/src/utils/Doc.js +372 -0
  174. package/src/utils/EventHandler.js +87 -0
  175. package/src/utils/ID.js +89 -0
  176. package/src/utils/IdMap.js +629 -0
  177. package/src/utils/IdSet.js +823 -0
  178. package/src/utils/RelativePosition.js +352 -0
  179. package/src/utils/Snapshot.js +220 -0
  180. package/src/utils/StructSet.js +137 -0
  181. package/src/utils/StructStore.js +289 -0
  182. package/src/utils/Transaction.js +489 -0
  183. package/src/utils/UndoManager.js +391 -0
  184. package/src/utils/UpdateDecoder.js +281 -0
  185. package/src/utils/UpdateEncoder.js +320 -0
  186. package/src/utils/YEvent.js +216 -0
  187. package/src/utils/delta-helpers.js +54 -0
  188. package/src/utils/encoding.js +623 -0
  189. package/src/utils/isParentOf.js +21 -0
  190. package/src/utils/logging.js +21 -0
  191. package/src/utils/types.js +28 -0
  192. package/src/utils/updates.js +715 -0
  193. package/tests/testHelper.js +600 -0
@@ -0,0 +1,372 @@
1
+ /**
2
+ * @module Y
3
+ */
4
+
5
+ import {
6
+ StructStore,
7
+ AbstractType,
8
+ YArray,
9
+ YText,
10
+ YMap,
11
+ YXmlElement,
12
+ YXmlFragment,
13
+ transact,
14
+ applyUpdate,
15
+ ContentDoc, Item, Transaction, // eslint-disable-line
16
+ encodeStateAsUpdate
17
+ } from '../internals.js'
18
+
19
+ import { ObservableV2 } from 'lib0/observable'
20
+ import * as random from 'lib0/random'
21
+ import * as map from 'lib0/map'
22
+ import * as array from 'lib0/array'
23
+ import * as promise from 'lib0/promise'
24
+
25
+ export const generateNewClientId = random.uint32
26
+
27
+ /**
28
+ * @typedef {import('../utils/types.js').YTypeConstructors} YTypeConstructors
29
+ */
30
+ /**
31
+ * @typedef {import('../utils/types.js').YType} YType
32
+ */
33
+
34
+ /**
35
+ * @typedef {Object} DocOpts
36
+ * @property {boolean} [DocOpts.gc=true] Disable garbage collection (default: gc=true)
37
+ * @property {function(Item):boolean} [DocOpts.gcFilter] Will be called before an Item is garbage collected. Return false to keep the Item.
38
+ * @property {string} [DocOpts.guid] Define a globally unique identifier for this document
39
+ * @property {string | null} [DocOpts.collectionid] Associate this document with a collection. This only plays a role if your provider has a concept of collection.
40
+ * @property {any} [DocOpts.meta] Any kind of meta information you want to associate with this document. If this is a subdocument, remote peers will store the meta information as well.
41
+ * @property {boolean} [DocOpts.autoLoad] If a subdocument, automatically load document. If this is a subdocument, remote peers will load the document as well automatically.
42
+ * @property {boolean} [DocOpts.shouldLoad] Whether the document should be synced by the provider now. This is toggled to true when you call ydoc.load()
43
+ * @property {boolean} [DocOpts.isSuggestionDoc] Set to true if this document merely suggests
44
+ * changes. If this flag is not set in a suggestion document, automatic formatting changes will be
45
+ * displayed as suggestions, which might not be intended.
46
+ */
47
+
48
+ /**
49
+ * @typedef {Object} DocEvents
50
+ * @property {function(Doc):void} DocEvents.destroy
51
+ * @property {function(Doc):void} DocEvents.load
52
+ * @property {function(boolean, Doc):void} DocEvents.sync
53
+ * @property {function(Uint8Array<ArrayBuffer>, any, Doc, Transaction):void} DocEvents.update
54
+ * @property {function(Uint8Array<ArrayBuffer>, any, Doc, Transaction):void} DocEvents.updateV2
55
+ * @property {function(Doc):void} DocEvents.beforeAllTransactions
56
+ * @property {function(Transaction, Doc):void} DocEvents.beforeTransaction
57
+ * @property {function(Transaction, Doc):void} DocEvents.beforeObserverCalls
58
+ * @property {function(Transaction, Doc):void} DocEvents.afterTransaction
59
+ * @property {function(Transaction, Doc):void} DocEvents.afterTransactionCleanup
60
+ * @property {function(Doc, Array<Transaction>):void} DocEvents.afterAllTransactions
61
+ * @property {function({ loaded: Set<Doc>, added: Set<Doc>, removed: Set<Doc> }, Doc, Transaction):void} DocEvents.subdocs
62
+ */
63
+
64
+ /**
65
+ * A Yjs instance handles the state of shared data.
66
+ * @extends ObservableV2<DocEvents>
67
+ */
68
+ export class Doc extends ObservableV2 {
69
+ /**
70
+ * @param {DocOpts} opts configuration
71
+ */
72
+ constructor ({ guid = random.uuidv4(), collectionid = null, gc = true, gcFilter = () => true, meta = null, autoLoad = false, shouldLoad = true, isSuggestionDoc = false } = {}) {
73
+ super()
74
+ this.gc = gc
75
+ this.gcFilter = gcFilter
76
+ this.clientID = generateNewClientId()
77
+ this.guid = guid
78
+ this.collectionid = collectionid
79
+ this.isSuggestionDoc = isSuggestionDoc
80
+ this.cleanupFormatting = !isSuggestionDoc
81
+ /**
82
+ * @type {Map<string, YType>}
83
+ */
84
+ this.share = new Map()
85
+ this.store = new StructStore()
86
+ /**
87
+ * @type {Transaction | null}
88
+ */
89
+ this._transaction = null
90
+ /**
91
+ * @type {Array<Transaction>}
92
+ */
93
+ this._transactionCleanups = []
94
+ /**
95
+ * @type {Set<Doc>}
96
+ */
97
+ this.subdocs = new Set()
98
+ /**
99
+ * If this document is a subdocument - a document integrated into another document - then _item is defined.
100
+ * @type {Item?}
101
+ */
102
+ this._item = null
103
+ this.shouldLoad = shouldLoad
104
+ this.autoLoad = autoLoad
105
+ this.meta = meta
106
+ /**
107
+ * This is set to true when the persistence provider loaded the document from the database or when the `sync` event fires.
108
+ * Note that not all providers implement this feature. Provider authors are encouraged to fire the `load` event when the doc content is loaded from the database.
109
+ *
110
+ * @type {boolean}
111
+ */
112
+ this.isLoaded = false
113
+ /**
114
+ * This is set to true when the connection provider has successfully synced with a backend.
115
+ * Note that when using peer-to-peer providers this event may not provide very useful.
116
+ * Also note that not all providers implement this feature. Provider authors are encouraged to fire
117
+ * the `sync` event when the doc has been synced (with `true` as a parameter) or if connection is
118
+ * lost (with false as a parameter).
119
+ */
120
+ this.isSynced = false
121
+ this.isDestroyed = false
122
+ /**
123
+ * Promise that resolves once the document has been loaded from a persistence provider.
124
+ */
125
+ this.whenLoaded = promise.create(resolve => {
126
+ this.on('load', () => {
127
+ this.isLoaded = true
128
+ resolve(this)
129
+ })
130
+ })
131
+ const provideSyncedPromise = () => promise.create(resolve => {
132
+ /**
133
+ * @param {boolean} isSynced
134
+ */
135
+ const eventHandler = (isSynced) => {
136
+ if (isSynced === undefined || isSynced === true) {
137
+ this.off('sync', eventHandler)
138
+ resolve()
139
+ }
140
+ }
141
+ this.on('sync', eventHandler)
142
+ })
143
+ this.on('sync', isSynced => {
144
+ if (isSynced === false && this.isSynced) {
145
+ this.whenSynced = provideSyncedPromise()
146
+ }
147
+ this.isSynced = isSynced === undefined || isSynced === true
148
+ if (this.isSynced && !this.isLoaded) {
149
+ this.emit('load', [this])
150
+ }
151
+ })
152
+ /**
153
+ * Promise that resolves once the document has been synced with a backend.
154
+ * This promise is recreated when the connection is lost.
155
+ * Note the documentation about the `isSynced` property.
156
+ */
157
+ this.whenSynced = provideSyncedPromise()
158
+ }
159
+
160
+ /**
161
+ * Notify the parent document that you request to load data into this subdocument (if it is a subdocument).
162
+ *
163
+ * `load()` might be used in the future to request any provider to load the most current data.
164
+ *
165
+ * It is safe to call `load()` multiple times.
166
+ */
167
+ load () {
168
+ const item = this._item
169
+ if (item !== null && !this.shouldLoad) {
170
+ transact(/** @type {any} */ (item.parent).doc, transaction => {
171
+ transaction.subdocsLoaded.add(this)
172
+ }, null, true)
173
+ }
174
+ this.shouldLoad = true
175
+ }
176
+
177
+ getSubdocs () {
178
+ return this.subdocs
179
+ }
180
+
181
+ getSubdocGuids () {
182
+ return new Set(array.from(this.subdocs).map(doc => doc.guid))
183
+ }
184
+
185
+ /**
186
+ * Changes that happen inside of a transaction are bundled. This means that
187
+ * the observer fires _after_ the transaction is finished and that all changes
188
+ * that happened inside of the transaction are sent as one message to the
189
+ * other peers.
190
+ *
191
+ * @template T
192
+ * @param {function(Transaction):T} f The function that should be executed as a transaction
193
+ * @param {any} [origin] Origin of who started the transaction. Will be stored on transaction.origin
194
+ * @return T
195
+ *
196
+ * @public
197
+ */
198
+ transact (f, origin = null) {
199
+ return transact(this, f, origin)
200
+ }
201
+
202
+ /**
203
+ * Define a shared data type.
204
+ *
205
+ * Multiple calls of `ydoc.get(name, TypeConstructor)` yield the same result
206
+ * and do not overwrite each other. I.e.
207
+ * `ydoc.get(name, Y.Array) === ydoc.get(name, Y.Array)`
208
+ *
209
+ * After this method is called, the type is also available on `ydoc.share.get(name)`.
210
+ *
211
+ * *Best Practices:*
212
+ * Define all types right after the Y.Doc instance is created and store them in a separate object.
213
+ * Also use the typed methods `getText(name)`, `getArray(name)`, ..
214
+ *
215
+ * @template {YTypeConstructors} [TypeC=typeof AbstractType]
216
+ * @example
217
+ * const ydoc = new Y.Doc(..)
218
+ * const appState = {
219
+ * document: ydoc.getText('document')
220
+ * comments: ydoc.getArray('comments')
221
+ * }
222
+ *
223
+ * @param {string} name
224
+ * @param {TypeC} TypeConstructor The constructor of the type definition. E.g. Y.Text, Y.Array, Y.Map, ...
225
+ * @return {AbstractType} The created type. Constructed with TypeConstructor
226
+ *
227
+ * @public
228
+ */
229
+ get (name, TypeConstructor = /** @type {any} */ (AbstractType)) {
230
+ const type = map.setIfUndefined(this.share, name, () => {
231
+ // @ts-ignore
232
+ const t = new TypeConstructor()
233
+ t._integrate(this, null)
234
+ return t
235
+ })
236
+ const Constr = type.constructor
237
+ // @ts-ignore
238
+ if (TypeConstructor !== AbstractType && Constr !== TypeConstructor) {
239
+ if (Constr === AbstractType) {
240
+ // @ts-ignore
241
+ const t = new TypeConstructor()
242
+ t._map = type._map
243
+ type._map.forEach(/** @param {Item?} n */ n => {
244
+ for (; n !== null; n = n.left) {
245
+ // @ts-ignore
246
+ n.parent = t
247
+ }
248
+ })
249
+ t._start = type._start
250
+ for (let n = t._start; n !== null; n = n.right) {
251
+ n.parent = t
252
+ }
253
+ t._length = type._length
254
+ this.share.set(name, t)
255
+ t._integrate(this, null)
256
+ return /** @type {InstanceType<TypeC>} */ (t)
257
+ } else {
258
+ throw new Error(`Type with the name ${name} has already been defined with a different constructor`)
259
+ }
260
+ }
261
+ return /** @type {InstanceType<TypeC>} */ (type)
262
+ }
263
+
264
+ /**
265
+ * @template T
266
+ * @param {string} [name]
267
+ * @return {YArray<T>}
268
+ *
269
+ * @public
270
+ */
271
+ getArray (name = '') {
272
+ return /** @type {YArray<any>} */ (this.get(name, YArray))
273
+ }
274
+
275
+ /**
276
+ * @param {string} [name]
277
+ * @return {YText}
278
+ *
279
+ * @public
280
+ */
281
+ getText (name = '') {
282
+ return /** @type {YText} */ (this.get(name, YText))
283
+ }
284
+
285
+ /**
286
+ * @template T
287
+ * @param {string} [name]
288
+ * @return {YMap<T>}
289
+ *
290
+ * @public
291
+ */
292
+ getMap (name = '') {
293
+ return /** @type {YMap<T>} */ (this.get(name, YMap))
294
+ }
295
+
296
+ /**
297
+ * @param {string} [name]
298
+ * @return {YXmlElement}
299
+ *
300
+ * @public
301
+ */
302
+ getXmlElement (name = '') {
303
+ return /** @type {YXmlElement<{[key:string]:string}>} */ (this.get(name, YXmlElement))
304
+ }
305
+
306
+ /**
307
+ * @param {string} [name]
308
+ * @return {YXmlFragment}
309
+ *
310
+ * @public
311
+ */
312
+ getXmlFragment (name = '') {
313
+ return /** @type {YXmlFragment} */ (this.get(name, YXmlFragment))
314
+ }
315
+
316
+ /**
317
+ * Converts the entire document into a js object, recursively traversing each yjs type
318
+ * Doesn't log types that have not been defined (using ydoc.getType(..)).
319
+ *
320
+ * @deprecated Do not use this method and rather call toJSON directly on the shared types.
321
+ *
322
+ * @return {Object<string, any>}
323
+ */
324
+ toJSON () {
325
+ /**
326
+ * @type {Object<string, any>}
327
+ */
328
+ const doc = {}
329
+
330
+ this.share.forEach((value, key) => {
331
+ doc[key] = value.toJSON()
332
+ })
333
+
334
+ return doc
335
+ }
336
+
337
+ /**
338
+ * Emit `destroy` event and unregister all event handlers.
339
+ */
340
+ destroy () {
341
+ this.isDestroyed = true
342
+ array.from(this.subdocs).forEach(subdoc => subdoc.destroy())
343
+ const item = this._item
344
+ if (item !== null) {
345
+ this._item = null
346
+ const content = /** @type {ContentDoc} */ (item.content)
347
+ content.doc = new Doc({ guid: this.guid, ...content.opts, shouldLoad: false })
348
+ content.doc._item = item
349
+ transact(/** @type {any} */ (item).parent.doc, transaction => {
350
+ const doc = content.doc
351
+ if (!item.deleted) {
352
+ transaction.subdocsAdded.add(doc)
353
+ }
354
+ transaction.subdocsRemoved.add(this)
355
+ }, null, true)
356
+ }
357
+ // @ts-ignore
358
+ this.emit('destroyed', [true]) // DEPRECATED!
359
+ this.emit('destroy', [this])
360
+ super.destroy()
361
+ }
362
+ }
363
+
364
+ /**
365
+ * @param {Doc} ydoc
366
+ * @param {DocOpts} [opts]
367
+ */
368
+ export const cloneDoc = (ydoc, opts) => {
369
+ const clone = new Doc(opts)
370
+ applyUpdate(clone, encodeStateAsUpdate(ydoc))
371
+ return clone
372
+ }
@@ -0,0 +1,87 @@
1
+ import * as f from 'lib0/function'
2
+
3
+ /**
4
+ * General event handler implementation.
5
+ *
6
+ * @template ARG0, ARG1
7
+ *
8
+ * @private
9
+ */
10
+ export class EventHandler {
11
+ constructor () {
12
+ /**
13
+ * @type {Array<function(ARG0, ARG1):void>}
14
+ */
15
+ this.l = []
16
+ }
17
+ }
18
+
19
+ /**
20
+ * @template ARG0,ARG1
21
+ * @returns {EventHandler<ARG0,ARG1>}
22
+ *
23
+ * @private
24
+ * @function
25
+ */
26
+ export const createEventHandler = () => new EventHandler()
27
+
28
+ /**
29
+ * Adds an event listener that is called when
30
+ * {@link EventHandler#callEventListeners} is called.
31
+ *
32
+ * @template ARG0,ARG1
33
+ * @param {EventHandler<ARG0,ARG1>} eventHandler
34
+ * @param {function(ARG0,ARG1):void} f The event handler.
35
+ *
36
+ * @private
37
+ * @function
38
+ */
39
+ export const addEventHandlerListener = (eventHandler, f) =>
40
+ eventHandler.l.push(f)
41
+
42
+ /**
43
+ * Removes an event listener.
44
+ *
45
+ * @template ARG0,ARG1
46
+ * @param {EventHandler<ARG0,ARG1>} eventHandler
47
+ * @param {function(ARG0,ARG1):void} f The event handler that was added with
48
+ * {@link EventHandler#addEventListener}
49
+ *
50
+ * @private
51
+ * @function
52
+ */
53
+ export const removeEventHandlerListener = (eventHandler, f) => {
54
+ const l = eventHandler.l
55
+ const len = l.length
56
+ eventHandler.l = l.filter(g => f !== g)
57
+ if (len === eventHandler.l.length) {
58
+ console.error('[yjs] Tried to remove event handler that doesn\'t exist.')
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Removes all event listeners.
64
+ * @template ARG0,ARG1
65
+ * @param {EventHandler<ARG0,ARG1>} eventHandler
66
+ *
67
+ * @private
68
+ * @function
69
+ */
70
+ export const removeAllEventHandlerListeners = eventHandler => {
71
+ eventHandler.l.length = 0
72
+ }
73
+
74
+ /**
75
+ * Call all event listeners that were added via
76
+ * {@link EventHandler#addEventListener}.
77
+ *
78
+ * @template ARG0,ARG1
79
+ * @param {EventHandler<ARG0,ARG1>} eventHandler
80
+ * @param {ARG0} arg0
81
+ * @param {ARG1} arg1
82
+ *
83
+ * @private
84
+ * @function
85
+ */
86
+ export const callEventHandlerListeners = (eventHandler, arg0, arg1) =>
87
+ f.callAll(eventHandler.l, [arg0, arg1])
@@ -0,0 +1,89 @@
1
+ import { AbstractType } from '../internals.js' // eslint-disable-line
2
+
3
+ import * as decoding from 'lib0/decoding'
4
+ import * as encoding from 'lib0/encoding'
5
+ import * as error from 'lib0/error'
6
+
7
+ export class ID {
8
+ /**
9
+ * @param {number} client client id
10
+ * @param {number} clock unique per client id, continuous number
11
+ */
12
+ constructor (client, clock) {
13
+ /**
14
+ * Client id
15
+ * @type {number}
16
+ */
17
+ this.client = client
18
+ /**
19
+ * unique per client id, continuous number
20
+ * @type {number}
21
+ */
22
+ this.clock = clock
23
+ }
24
+ }
25
+
26
+ /**
27
+ * @param {ID | null} a
28
+ * @param {ID | null} b
29
+ * @return {boolean}
30
+ *
31
+ * @function
32
+ */
33
+ export const compareIDs = (a, b) => a === b || (a !== null && b !== null && a.client === b.client && a.clock === b.clock)
34
+
35
+ /**
36
+ * @param {number} client
37
+ * @param {number} clock
38
+ *
39
+ * @private
40
+ * @function
41
+ */
42
+ export const createID = (client, clock) => new ID(client, clock)
43
+
44
+ /**
45
+ * @param {encoding.Encoder} encoder
46
+ * @param {ID} id
47
+ *
48
+ * @private
49
+ * @function
50
+ */
51
+ export const writeID = (encoder, id) => {
52
+ encoding.writeVarUint(encoder, id.client)
53
+ encoding.writeVarUint(encoder, id.clock)
54
+ }
55
+
56
+ /**
57
+ * Read ID.
58
+ * * If first varUint read is 0xFFFFFF a RootID is returned.
59
+ * * Otherwise an ID is returned
60
+ *
61
+ * @param {decoding.Decoder} decoder
62
+ * @return {ID}
63
+ *
64
+ * @private
65
+ * @function
66
+ */
67
+ export const readID = decoder =>
68
+ createID(decoding.readVarUint(decoder), decoding.readVarUint(decoder))
69
+
70
+ /**
71
+ * The top types are mapped from y.share.get(keyname) => type.
72
+ * `type` does not store any information about the `keyname`.
73
+ * This function finds the correct `keyname` for `type` and throws otherwise.
74
+ *
75
+ * @param {AbstractType<any>} type
76
+ * @return {string}
77
+ *
78
+ * @private
79
+ * @function
80
+ */
81
+ export const findRootTypeKey = type => {
82
+ // @ts-ignore _y must be defined, otherwise unexpected case
83
+ for (const [key, value] of type.doc.share.entries()) {
84
+ if (value === type) {
85
+ return key
86
+ }
87
+ }
88
+ throw error.unexpectedCase()
89
+ }