vis-data 7.1.0 → 7.1.3

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 (47) hide show
  1. package/declarations/data-interface.d.ts +1 -28
  2. package/declarations/data-interface.d.ts.map +1 -1
  3. package/declarations/data-pipe.d.ts +5 -9
  4. package/declarations/data-pipe.d.ts.map +1 -1
  5. package/declarations/data-set-check.d.ts +0 -1
  6. package/declarations/data-set-check.d.ts.map +1 -1
  7. package/declarations/data-set-part.d.ts +1 -1
  8. package/declarations/data-set-part.d.ts.map +1 -1
  9. package/declarations/data-set.d.ts +4 -17
  10. package/declarations/data-set.d.ts.map +1 -1
  11. package/declarations/data-stream.d.ts +1 -17
  12. package/declarations/data-stream.d.ts.map +1 -1
  13. package/declarations/data-view-check.d.ts +0 -1
  14. package/declarations/data-view-check.d.ts.map +1 -1
  15. package/declarations/data-view.d.ts +4 -2
  16. package/declarations/data-view.d.ts.map +1 -1
  17. package/declarations/queue.d.ts +3 -2
  18. package/declarations/queue.d.ts.map +1 -1
  19. package/dist/esm.js +7435 -3483
  20. package/dist/esm.js.map +1 -1
  21. package/dist/umd.js +11969 -8016
  22. package/dist/umd.js.map +1 -1
  23. package/esnext/esm/vis-data.js +162 -266
  24. package/esnext/esm/vis-data.js.map +1 -1
  25. package/esnext/esm/vis-data.min.js +3 -17
  26. package/esnext/esm/vis-data.min.js.map +1 -1
  27. package/esnext/umd/vis-data.js +2009 -2115
  28. package/esnext/umd/vis-data.js.map +1 -1
  29. package/esnext/umd/vis-data.min.js +3 -18
  30. package/esnext/umd/vis-data.min.js.map +1 -1
  31. package/package.json +75 -27
  32. package/peer/esm/vis-data.js +7428 -3475
  33. package/peer/esm/vis-data.js.map +1 -1
  34. package/peer/esm/vis-data.min.js +8 -41
  35. package/peer/esm/vis-data.min.js.map +1 -1
  36. package/peer/umd/vis-data.js +11928 -7975
  37. package/peer/umd/vis-data.js.map +1 -1
  38. package/peer/umd/vis-data.min.js +9 -42
  39. package/peer/umd/vis-data.min.js.map +1 -1
  40. package/standalone/esm/vis-data.js +7428 -3475
  41. package/standalone/esm/vis-data.js.map +1 -1
  42. package/standalone/esm/vis-data.min.js +8 -41
  43. package/standalone/esm/vis-data.min.js.map +1 -1
  44. package/standalone/umd/vis-data.js +11928 -7975
  45. package/standalone/umd/vis-data.js.map +1 -1
  46. package/standalone/umd/vis-data.min.js +9 -42
  47. package/standalone/umd/vis-data.min.js.map +1 -1
@@ -4,8 +4,8 @@
4
4
  *
5
5
  * Manage unstructured data using DataSet. Add, update, and remove data, and listen for changes in the data.
6
6
  *
7
- * @version 7.1.0
8
- * @date 2020-10-13T20:44:00.711Z
7
+ * @version 7.1.3
8
+ * @date 2022-03-02T13:02:54.265Z
9
9
  *
10
10
  * @copyright (c) 2011-2017 Almende B.V, http://almende.com
11
11
  * @copyright (c) 2017-2019 visjs contributors, https://github.com/visjs
@@ -25,2128 +25,2022 @@
25
25
  */
26
26
 
27
27
  (function (global, factory) {
28
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vis-util/esnext/umd/vis-util.js'), require('uuid')) :
29
- typeof define === 'function' && define.amd ? define(['exports', 'vis-util/esnext/umd/vis-util.js', 'uuid'], factory) :
30
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.vis = global.vis || {}, global.vis, global.uuidv4));
31
- }(this, (function (exports, esnext, uuid) {
32
- /*! *****************************************************************************
33
- Copyright (c) Microsoft Corporation.
34
-
35
- Permission to use, copy, modify, and/or distribute this software for any
36
- purpose with or without fee is hereby granted.
37
-
38
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
39
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
40
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
41
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
42
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
43
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
44
- PERFORMANCE OF THIS SOFTWARE.
45
- ***************************************************************************** */
46
-
47
- function __classPrivateFieldGet(receiver, privateMap) {
48
- if (!privateMap.has(receiver)) {
49
- throw new TypeError("attempted to get private field on non-instance");
50
- }
51
- return privateMap.get(receiver);
52
- }
53
-
54
- function __classPrivateFieldSet(receiver, privateMap, value) {
55
- if (!privateMap.has(receiver)) {
56
- throw new TypeError("attempted to set private field on non-instance");
57
- }
58
- privateMap.set(receiver, value);
59
- return value;
60
- }
28
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vis-util/esnext/umd/vis-util.js'), require('uuid')) :
29
+ typeof define === 'function' && define.amd ? define(['exports', 'vis-util/esnext/umd/vis-util.js', 'uuid'], factory) :
30
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.vis = global.vis || {}, global.vis, global.uuidv4));
31
+ })(this, (function (exports, esnext, uuid) {
32
+ /**
33
+ * Create new data pipe.
34
+ *
35
+ * @param from - The source data set or data view.
36
+ * @remarks
37
+ * Example usage:
38
+ * ```typescript
39
+ * interface AppItem {
40
+ * whoami: string;
41
+ * appData: unknown;
42
+ * visData: VisItem;
43
+ * }
44
+ * interface VisItem {
45
+ * id: number;
46
+ * label: string;
47
+ * color: string;
48
+ * x: number;
49
+ * y: number;
50
+ * }
51
+ *
52
+ * const ds1 = new DataSet<AppItem, "whoami">([], { fieldId: "whoami" });
53
+ * const ds2 = new DataSet<VisItem, "id">();
54
+ *
55
+ * const pipe = createNewDataPipeFrom(ds1)
56
+ * .filter((item): boolean => item.enabled === true)
57
+ * .map<VisItem, "id">((item): VisItem => item.visData)
58
+ * .to(ds2);
59
+ *
60
+ * pipe.start();
61
+ * ```
62
+ * @returns A factory whose methods can be used to configure the pipe.
63
+ */
64
+ function createNewDataPipeFrom(from) {
65
+ return new DataPipeUnderConstruction(from);
66
+ }
67
+ /**
68
+ * Internal implementation of the pipe. This should be accessible only through
69
+ * `createNewDataPipeFrom` from the outside.
70
+ *
71
+ * @typeParam SI - Source item type.
72
+ * @typeParam SP - Source item type's id property name.
73
+ * @typeParam TI - Target item type.
74
+ * @typeParam TP - Target item type's id property name.
75
+ */
76
+ class SimpleDataPipe {
77
+ /**
78
+ * Create a new data pipe.
79
+ *
80
+ * @param _source - The data set or data view that will be observed.
81
+ * @param _transformers - An array of transforming functions to be used to
82
+ * filter or transform the items in the pipe.
83
+ * @param _target - The data set or data view that will receive the items.
84
+ */
85
+ constructor(_source, _transformers, _target) {
86
+ this._source = _source;
87
+ this._transformers = _transformers;
88
+ this._target = _target;
89
+ /**
90
+ * Bound listeners for use with `DataInterface['on' | 'off']`.
91
+ */
92
+ this._listeners = {
93
+ add: this._add.bind(this),
94
+ remove: this._remove.bind(this),
95
+ update: this._update.bind(this),
96
+ };
97
+ }
98
+ /** @inheritDoc */
99
+ all() {
100
+ this._target.update(this._transformItems(this._source.get()));
101
+ return this;
102
+ }
103
+ /** @inheritDoc */
104
+ start() {
105
+ this._source.on("add", this._listeners.add);
106
+ this._source.on("remove", this._listeners.remove);
107
+ this._source.on("update", this._listeners.update);
108
+ return this;
109
+ }
110
+ /** @inheritDoc */
111
+ stop() {
112
+ this._source.off("add", this._listeners.add);
113
+ this._source.off("remove", this._listeners.remove);
114
+ this._source.off("update", this._listeners.update);
115
+ return this;
116
+ }
117
+ /**
118
+ * Apply the transformers to the items.
119
+ *
120
+ * @param items - The items to be transformed.
121
+ * @returns The transformed items.
122
+ */
123
+ _transformItems(items) {
124
+ return this._transformers.reduce((items, transform) => {
125
+ return transform(items);
126
+ }, items);
127
+ }
128
+ /**
129
+ * Handle an add event.
130
+ *
131
+ * @param _name - Ignored.
132
+ * @param payload - The payload containing the ids of the added items.
133
+ */
134
+ _add(_name, payload) {
135
+ if (payload == null) {
136
+ return;
137
+ }
138
+ this._target.add(this._transformItems(this._source.get(payload.items)));
139
+ }
140
+ /**
141
+ * Handle an update event.
142
+ *
143
+ * @param _name - Ignored.
144
+ * @param payload - The payload containing the ids of the updated items.
145
+ */
146
+ _update(_name, payload) {
147
+ if (payload == null) {
148
+ return;
149
+ }
150
+ this._target.update(this._transformItems(this._source.get(payload.items)));
151
+ }
152
+ /**
153
+ * Handle a remove event.
154
+ *
155
+ * @param _name - Ignored.
156
+ * @param payload - The payload containing the data of the removed items.
157
+ */
158
+ _remove(_name, payload) {
159
+ if (payload == null) {
160
+ return;
161
+ }
162
+ this._target.remove(this._transformItems(payload.oldData));
163
+ }
164
+ }
165
+ /**
166
+ * Internal implementation of the pipe factory. This should be accessible
167
+ * only through `createNewDataPipeFrom` from the outside.
168
+ *
169
+ * @typeParam TI - Target item type.
170
+ * @typeParam TP - Target item type's id property name.
171
+ */
172
+ class DataPipeUnderConstruction {
173
+ /**
174
+ * Create a new data pipe factory. This is an internal constructor that
175
+ * should never be called from outside of this file.
176
+ *
177
+ * @param _source - The source data set or data view for this pipe.
178
+ */
179
+ constructor(_source) {
180
+ this._source = _source;
181
+ /**
182
+ * Array transformers used to transform items within the pipe. This is typed
183
+ * as any for the sake of simplicity.
184
+ */
185
+ this._transformers = [];
186
+ }
187
+ /**
188
+ * Filter the items.
189
+ *
190
+ * @param callback - A filtering function that returns true if given item
191
+ * should be piped and false if not.
192
+ * @returns This factory for further configuration.
193
+ */
194
+ filter(callback) {
195
+ this._transformers.push((input) => input.filter(callback));
196
+ return this;
197
+ }
198
+ /**
199
+ * Map each source item to a new type.
200
+ *
201
+ * @param callback - A mapping function that takes a source item and returns
202
+ * corresponding mapped item.
203
+ * @typeParam TI - Target item type.
204
+ * @typeParam TP - Target item type's id property name.
205
+ * @returns This factory for further configuration.
206
+ */
207
+ map(callback) {
208
+ this._transformers.push((input) => input.map(callback));
209
+ return this;
210
+ }
211
+ /**
212
+ * Map each source item to zero or more items of a new type.
213
+ *
214
+ * @param callback - A mapping function that takes a source item and returns
215
+ * an array of corresponding mapped items.
216
+ * @typeParam TI - Target item type.
217
+ * @typeParam TP - Target item type's id property name.
218
+ * @returns This factory for further configuration.
219
+ */
220
+ flatMap(callback) {
221
+ this._transformers.push((input) => input.flatMap(callback));
222
+ return this;
223
+ }
224
+ /**
225
+ * Connect this pipe to given data set.
226
+ *
227
+ * @param target - The data set that will receive the items from this pipe.
228
+ * @returns The pipe connected between given data sets and performing
229
+ * configured transformation on the processed items.
230
+ */
231
+ to(target) {
232
+ return new SimpleDataPipe(this._source, this._transformers, target);
233
+ }
234
+ }
61
235
 
62
- var _transformers_1;
63
- /**
64
- * Create new data pipe.
65
- *
66
- * @param from - The source data set or data view.
67
- *
68
- * @remarks
69
- * Example usage:
70
- * ```typescript
71
- * interface AppItem {
72
- * whoami: string;
73
- * appData: unknown;
74
- * visData: VisItem;
75
- * }
76
- * interface VisItem {
77
- * id: number;
78
- * label: string;
79
- * color: string;
80
- * x: number;
81
- * y: number;
82
- * }
83
- *
84
- * const ds1 = new DataSet<AppItem, "whoami">([], { fieldId: "whoami" });
85
- * const ds2 = new DataSet<VisItem, "id">();
86
- *
87
- * const pipe = createNewDataPipeFrom(ds1)
88
- * .filter((item): boolean => item.enabled === true)
89
- * .map<VisItem, "id">((item): VisItem => item.visData)
90
- * .to(ds2);
91
- *
92
- * pipe.start();
93
- * ```
94
- *
95
- * @returns A factory whose methods can be used to configure the pipe.
96
- */
97
- function createNewDataPipeFrom(from) {
98
- return new DataPipeUnderConstruction(from);
99
- }
100
- /**
101
- * Internal implementation of the pipe. This should be accessible only through
102
- * `createNewDataPipeFrom` from the outside.
103
- *
104
- * @typeParam SI - Source item type.
105
- * @typeParam SP - Source item type's id property name.
106
- * @typeParam TI - Target item type.
107
- * @typeParam TP - Target item type's id property name.
108
- */
109
- class SimpleDataPipe {
110
- /**
111
- * Create a new data pipe.
112
- *
113
- * @param _source - The data set or data view that will be observed.
114
- * @param _transformers - An array of transforming functions to be used to
115
- * filter or transform the items in the pipe.
116
- * @param _target - The data set or data view that will receive the items.
117
- */
118
- constructor(_source, _transformers, _target) {
119
- this._source = _source;
120
- this._transformers = _transformers;
121
- this._target = _target;
122
- /**
123
- * Bound listeners for use with `DataInterface['on' | 'off']`.
124
- */
125
- this._listeners = {
126
- add: this._add.bind(this),
127
- remove: this._remove.bind(this),
128
- update: this._update.bind(this),
129
- };
130
- }
131
- /** @inheritDoc */
132
- all() {
133
- this._target.update(this._transformItems(this._source.get()));
134
- return this;
135
- }
136
- /** @inheritDoc */
137
- start() {
138
- this._source.on("add", this._listeners.add);
139
- this._source.on("remove", this._listeners.remove);
140
- this._source.on("update", this._listeners.update);
141
- return this;
142
- }
143
- /** @inheritDoc */
144
- stop() {
145
- this._source.off("add", this._listeners.add);
146
- this._source.off("remove", this._listeners.remove);
147
- this._source.off("update", this._listeners.update);
148
- return this;
149
- }
150
- /**
151
- * Apply the transformers to the items.
152
- *
153
- * @param items - The items to be transformed.
154
- *
155
- * @returns The transformed items.
156
- */
157
- _transformItems(items) {
158
- return this._transformers.reduce((items, transform) => {
159
- return transform(items);
160
- }, items);
161
- }
162
- /**
163
- * Handle an add event.
164
- *
165
- * @param _name - Ignored.
166
- * @param payload - The payload containing the ids of the added items.
167
- */
168
- _add(_name, payload) {
169
- if (payload == null) {
170
- return;
171
- }
172
- this._target.add(this._transformItems(this._source.get(payload.items)));
173
- }
174
- /**
175
- * Handle an update event.
176
- *
177
- * @param _name - Ignored.
178
- * @param payload - The payload containing the ids of the updated items.
179
- */
180
- _update(_name, payload) {
181
- if (payload == null) {
182
- return;
183
- }
184
- this._target.update(this._transformItems(this._source.get(payload.items)));
185
- }
186
- /**
187
- * Handle a remove event.
188
- *
189
- * @param _name - Ignored.
190
- * @param payload - The payload containing the data of the removed items.
191
- */
192
- _remove(_name, payload) {
193
- if (payload == null) {
194
- return;
195
- }
196
- this._target.remove(this._transformItems(payload.oldData));
197
- }
198
- }
199
- /**
200
- * Internal implementation of the pipe factory. This should be accessible
201
- * only through `createNewDataPipeFrom` from the outside.
202
- *
203
- * @typeParam TI - Target item type.
204
- * @typeParam TP - Target item type's id property name.
205
- */
206
- class DataPipeUnderConstruction {
207
- /**
208
- * Create a new data pipe factory. This is an internal constructor that
209
- * should never be called from outside of this file.
210
- *
211
- * @param _source - The source data set or data view for this pipe.
212
- */
213
- constructor(_source) {
214
- this._source = _source;
215
- /**
216
- * Array transformers used to transform items within the pipe. This is typed
217
- * as any for the sake of simplicity.
218
- */
219
- _transformers_1.set(this, []);
220
- }
221
- /**
222
- * Filter the items.
223
- *
224
- * @param callback - A filtering function that returns true if given item
225
- * should be piped and false if not.
226
- *
227
- * @returns This factory for further configuration.
228
- */
229
- filter(callback) {
230
- __classPrivateFieldGet(this, _transformers_1).push((input) => input.filter(callback));
231
- return this;
232
- }
233
- /**
234
- * Map each source item to a new type.
235
- *
236
- * @param callback - A mapping function that takes a source item and returns
237
- * corresponding mapped item.
238
- *
239
- * @typeParam TI - Target item type.
240
- * @typeParam TP - Target item type's id property name.
241
- *
242
- * @returns This factory for further configuration.
243
- */
244
- map(callback) {
245
- __classPrivateFieldGet(this, _transformers_1).push((input) => input.map(callback));
246
- return this;
247
- }
248
- /**
249
- * Map each source item to zero or more items of a new type.
250
- *
251
- * @param callback - A mapping function that takes a source item and returns
252
- * an array of corresponding mapped items.
253
- *
254
- * @typeParam TI - Target item type.
255
- * @typeParam TP - Target item type's id property name.
256
- *
257
- * @returns This factory for further configuration.
258
- */
259
- flatMap(callback) {
260
- __classPrivateFieldGet(this, _transformers_1).push((input) => input.flatMap(callback));
261
- return this;
262
- }
263
- /**
264
- * Connect this pipe to given data set.
265
- *
266
- * @param target - The data set that will receive the items from this pipe.
267
- *
268
- * @returns The pipe connected between given data sets and performing
269
- * configured transformation on the processed items.
270
- */
271
- to(target) {
272
- return new SimpleDataPipe(this._source, __classPrivateFieldGet(this, _transformers_1), target);
273
- }
274
- }
275
- _transformers_1 = new WeakMap();
236
+ /**
237
+ * Determine whether a value can be used as an id.
238
+ *
239
+ * @param value - Input value of unknown type.
240
+ * @returns True if the value is valid id, false otherwise.
241
+ */
242
+ function isId(value) {
243
+ return typeof value === "string" || typeof value === "number";
244
+ }
276
245
 
277
- /**
278
- * Determine whether a value can be used as an id.
279
- *
280
- * @param value - Input value of unknown type.
281
- *
282
- * @returns True if the value is valid id, false otherwise.
283
- */
284
- function isId(value) {
285
- return typeof value === "string" || typeof value === "number";
286
- }
246
+ /**
247
+ * A queue.
248
+ *
249
+ * @typeParam T - The type of method names to be replaced by queued versions.
250
+ */
251
+ class Queue {
252
+ /**
253
+ * Construct a new Queue.
254
+ *
255
+ * @param options - Queue configuration.
256
+ */
257
+ constructor(options) {
258
+ this._queue = [];
259
+ this._timeout = null;
260
+ this._extended = null;
261
+ // options
262
+ this.delay = null;
263
+ this.max = Infinity;
264
+ this.setOptions(options);
265
+ }
266
+ /**
267
+ * Update the configuration of the queue.
268
+ *
269
+ * @param options - Queue configuration.
270
+ */
271
+ setOptions(options) {
272
+ if (options && typeof options.delay !== "undefined") {
273
+ this.delay = options.delay;
274
+ }
275
+ if (options && typeof options.max !== "undefined") {
276
+ this.max = options.max;
277
+ }
278
+ this._flushIfNeeded();
279
+ }
280
+ /**
281
+ * Extend an object with queuing functionality.
282
+ * The object will be extended with a function flush, and the methods provided in options.replace will be replaced with queued ones.
283
+ *
284
+ * @param object - The object to be extended.
285
+ * @param options - Additional options.
286
+ * @returns The created queue.
287
+ */
288
+ static extend(object, options) {
289
+ const queue = new Queue(options);
290
+ if (object.flush !== undefined) {
291
+ throw new Error("Target object already has a property flush");
292
+ }
293
+ object.flush = () => {
294
+ queue.flush();
295
+ };
296
+ const methods = [
297
+ {
298
+ name: "flush",
299
+ original: undefined,
300
+ },
301
+ ];
302
+ if (options && options.replace) {
303
+ for (let i = 0; i < options.replace.length; i++) {
304
+ const name = options.replace[i];
305
+ methods.push({
306
+ name: name,
307
+ // @TODO: better solution?
308
+ original: object[name],
309
+ });
310
+ // @TODO: better solution?
311
+ queue.replace(object, name);
312
+ }
313
+ }
314
+ queue._extended = {
315
+ object: object,
316
+ methods: methods,
317
+ };
318
+ return queue;
319
+ }
320
+ /**
321
+ * Destroy the queue. The queue will first flush all queued actions, and in case it has extended an object, will restore the original object.
322
+ */
323
+ destroy() {
324
+ this.flush();
325
+ if (this._extended) {
326
+ const object = this._extended.object;
327
+ const methods = this._extended.methods;
328
+ for (let i = 0; i < methods.length; i++) {
329
+ const method = methods[i];
330
+ if (method.original) {
331
+ // @TODO: better solution?
332
+ object[method.name] = method.original;
333
+ }
334
+ else {
335
+ // @TODO: better solution?
336
+ delete object[method.name];
337
+ }
338
+ }
339
+ this._extended = null;
340
+ }
341
+ }
342
+ /**
343
+ * Replace a method on an object with a queued version.
344
+ *
345
+ * @param object - Object having the method.
346
+ * @param method - The method name.
347
+ */
348
+ replace(object, method) {
349
+ /* eslint-disable-next-line @typescript-eslint/no-this-alias -- Function this is necessary in the function bellow, so class this has to be saved into a variable here. */
350
+ const me = this;
351
+ const original = object[method];
352
+ if (!original) {
353
+ throw new Error("Method " + method + " undefined");
354
+ }
355
+ object[method] = function (...args) {
356
+ // add this call to the queue
357
+ me.queue({
358
+ args: args,
359
+ fn: original,
360
+ context: this,
361
+ });
362
+ };
363
+ }
364
+ /**
365
+ * Queue a call.
366
+ *
367
+ * @param entry - The function or entry to be queued.
368
+ */
369
+ queue(entry) {
370
+ if (typeof entry === "function") {
371
+ this._queue.push({ fn: entry });
372
+ }
373
+ else {
374
+ this._queue.push(entry);
375
+ }
376
+ this._flushIfNeeded();
377
+ }
378
+ /**
379
+ * Check whether the queue needs to be flushed.
380
+ */
381
+ _flushIfNeeded() {
382
+ // flush when the maximum is exceeded.
383
+ if (this._queue.length > this.max) {
384
+ this.flush();
385
+ }
386
+ // flush after a period of inactivity when a delay is configured
387
+ if (this._timeout != null) {
388
+ clearTimeout(this._timeout);
389
+ this._timeout = null;
390
+ }
391
+ if (this.queue.length > 0 && typeof this.delay === "number") {
392
+ this._timeout = setTimeout(() => {
393
+ this.flush();
394
+ }, this.delay);
395
+ }
396
+ }
397
+ /**
398
+ * Flush all queued calls
399
+ */
400
+ flush() {
401
+ this._queue.splice(0).forEach((entry) => {
402
+ entry.fn.apply(entry.context || entry.fn, entry.args || []);
403
+ });
404
+ }
405
+ }
287
406
 
288
- var _queue, _timeout, _extended;
289
- /**
290
- * A queue.
291
- *
292
- * @typeParam T - The type of method names to be replaced by queued versions.
293
- */
294
- class Queue {
295
- /**
296
- * Construct a new Queue.
297
- *
298
- * @param options - Queue configuration.
299
- */
300
- constructor(options) {
301
- _queue.set(this, []);
302
- _timeout.set(this, null);
303
- _extended.set(this, null);
304
- // options
305
- this.delay = null;
306
- this.max = Infinity;
307
- this.setOptions(options);
308
- }
309
- /**
310
- * Update the configuration of the queue.
311
- *
312
- * @param options - Queue configuration.
313
- */
314
- setOptions(options) {
315
- if (options && typeof options.delay !== "undefined") {
316
- this.delay = options.delay;
317
- }
318
- if (options && typeof options.max !== "undefined") {
319
- this.max = options.max;
320
- }
321
- this._flushIfNeeded();
322
- }
323
- /**
324
- * Extend an object with queuing functionality.
325
- * The object will be extended with a function flush, and the methods provided in options.replace will be replaced with queued ones.
326
- *
327
- * @param object - The object to be extended.
328
- * @param options - Additional options.
329
- *
330
- * @returns The created queue.
331
- */
332
- static extend(object, options) {
333
- const queue = new Queue(options);
334
- if (object.flush !== undefined) {
335
- throw new Error("Target object already has a property flush");
336
- }
337
- object.flush = () => {
338
- queue.flush();
339
- };
340
- const methods = [
341
- {
342
- name: "flush",
343
- original: undefined,
344
- },
345
- ];
346
- if (options && options.replace) {
347
- for (let i = 0; i < options.replace.length; i++) {
348
- const name = options.replace[i];
349
- methods.push({
350
- name: name,
351
- // @TODO: better solution?
352
- original: object[name],
353
- });
354
- // @TODO: better solution?
355
- queue.replace(object, name);
356
- }
357
- }
358
- __classPrivateFieldSet(queue, _extended, {
359
- object: object,
360
- methods: methods,
361
- });
362
- return queue;
363
- }
364
- /**
365
- * Destroy the queue. The queue will first flush all queued actions, and in case it has extended an object, will restore the original object.
366
- */
367
- destroy() {
368
- this.flush();
369
- if (__classPrivateFieldGet(this, _extended)) {
370
- const object = __classPrivateFieldGet(this, _extended).object;
371
- const methods = __classPrivateFieldGet(this, _extended).methods;
372
- for (let i = 0; i < methods.length; i++) {
373
- const method = methods[i];
374
- if (method.original) {
375
- // @TODO: better solution?
376
- object[method.name] = method.original;
377
- }
378
- else {
379
- // @TODO: better solution?
380
- delete object[method.name];
381
- }
382
- }
383
- __classPrivateFieldSet(this, _extended, null);
384
- }
385
- }
386
- /**
387
- * Replace a method on an object with a queued version.
388
- *
389
- * @param object - Object having the method.
390
- * @param method - The method name.
391
- */
392
- replace(object, method) {
393
- /* eslint-disable-next-line @typescript-eslint/no-this-alias -- Function this is necessary in the function bellow, so class this has to be saved into a variable here. */
394
- const me = this;
395
- const original = object[method];
396
- if (!original) {
397
- throw new Error("Method " + method + " undefined");
398
- }
399
- object[method] = function (...args) {
400
- // add this call to the queue
401
- me.queue({
402
- args: args,
403
- fn: original,
404
- context: this,
405
- });
406
- };
407
- }
408
- /**
409
- * Queue a call.
410
- *
411
- * @param entry - The function or entry to be queued.
412
- */
413
- queue(entry) {
414
- if (typeof entry === "function") {
415
- __classPrivateFieldGet(this, _queue).push({ fn: entry });
416
- }
417
- else {
418
- __classPrivateFieldGet(this, _queue).push(entry);
419
- }
420
- this._flushIfNeeded();
421
- }
422
- /**
423
- * Check whether the queue needs to be flushed.
424
- */
425
- _flushIfNeeded() {
426
- // flush when the maximum is exceeded.
427
- if (__classPrivateFieldGet(this, _queue).length > this.max) {
428
- this.flush();
429
- }
430
- // flush after a period of inactivity when a delay is configured
431
- if (__classPrivateFieldGet(this, _timeout) != null) {
432
- clearTimeout(__classPrivateFieldGet(this, _timeout));
433
- __classPrivateFieldSet(this, _timeout, null);
434
- }
435
- if (this.queue.length > 0 && typeof this.delay === "number") {
436
- __classPrivateFieldSet(this, _timeout, setTimeout(() => {
437
- this.flush();
438
- }, this.delay));
439
- }
440
- }
441
- /**
442
- * Flush all queued calls
443
- */
444
- flush() {
445
- __classPrivateFieldGet(this, _queue).splice(0).forEach((entry) => {
446
- entry.fn.apply(entry.context || entry.fn, entry.args || []);
447
- });
448
- }
449
- }
450
- _queue = new WeakMap(), _timeout = new WeakMap(), _extended = new WeakMap();
407
+ /**
408
+ * [[DataSet]] code that can be reused in [[DataView]] or other similar implementations of [[DataInterface]].
409
+ *
410
+ * @typeParam Item - Item type that may or may not have an id.
411
+ * @typeParam IdProp - Name of the property that contains the id.
412
+ */
413
+ class DataSetPart {
414
+ constructor() {
415
+ this._subscribers = {
416
+ "*": [],
417
+ add: [],
418
+ remove: [],
419
+ update: [],
420
+ };
421
+ /**
422
+ * @deprecated Use on instead (PS: DataView.subscribe === DataView.on).
423
+ */
424
+ this.subscribe = DataSetPart.prototype.on;
425
+ /**
426
+ * @deprecated Use off instead (PS: DataView.unsubscribe === DataView.off).
427
+ */
428
+ this.unsubscribe = DataSetPart.prototype.off;
429
+ }
430
+ /**
431
+ * Trigger an event
432
+ *
433
+ * @param event - Event name.
434
+ * @param payload - Event payload.
435
+ * @param senderId - Id of the sender.
436
+ */
437
+ _trigger(event, payload, senderId) {
438
+ if (event === "*") {
439
+ throw new Error("Cannot trigger event *");
440
+ }
441
+ [...this._subscribers[event], ...this._subscribers["*"]].forEach((subscriber) => {
442
+ subscriber(event, payload, senderId != null ? senderId : null);
443
+ });
444
+ }
445
+ /**
446
+ * Subscribe to an event, add an event listener.
447
+ *
448
+ * @remarks Non-function callbacks are ignored.
449
+ * @param event - Event name.
450
+ * @param callback - Callback method.
451
+ */
452
+ on(event, callback) {
453
+ if (typeof callback === "function") {
454
+ this._subscribers[event].push(callback);
455
+ }
456
+ // @TODO: Maybe throw for invalid callbacks?
457
+ }
458
+ /**
459
+ * Unsubscribe from an event, remove an event listener.
460
+ *
461
+ * @remarks If the same callback was subscribed more than once **all** occurences will be removed.
462
+ * @param event - Event name.
463
+ * @param callback - Callback method.
464
+ */
465
+ off(event, callback) {
466
+ this._subscribers[event] = this._subscribers[event].filter((subscriber) => subscriber !== callback);
467
+ }
468
+ }
451
469
 
452
- var _subscribers;
453
- /**
454
- * [[DataSet]] code that can be reused in [[DataView]] or other similar implementations of [[DataInterface]].
455
- *
456
- * @typeParam Item - Item type that may or may not have an id.
457
- * @typeParam IdProp - Name of the property that contains the id.
458
- */
459
- class DataSetPart {
460
- constructor() {
461
- _subscribers.set(this, {
462
- "*": [],
463
- add: [],
464
- remove: [],
465
- update: [],
466
- });
467
- /**
468
- * @deprecated Use on instead (PS: DataView.subscribe === DataView.on).
469
- */
470
- this.subscribe = DataSetPart.prototype.on;
471
- /**
472
- * @deprecated Use off instead (PS: DataView.unsubscribe === DataView.off).
473
- */
474
- this.unsubscribe = DataSetPart.prototype.off;
475
- }
476
- /**
477
- * Trigger an event
478
- *
479
- * @param event - Event name.
480
- * @param payload - Event payload.
481
- * @param senderId - Id of the sender.
482
- */
483
- _trigger(event, payload, senderId) {
484
- if (event === "*") {
485
- throw new Error("Cannot trigger event *");
486
- }
487
- [...__classPrivateFieldGet(this, _subscribers)[event], ...__classPrivateFieldGet(this, _subscribers)["*"]].forEach((subscriber) => {
488
- subscriber(event, payload, senderId != null ? senderId : null);
489
- });
490
- }
491
- /**
492
- * Subscribe to an event, add an event listener.
493
- *
494
- * @remarks Non-function callbacks are ignored.
495
- *
496
- * @param event - Event name.
497
- * @param callback - Callback method.
498
- */
499
- on(event, callback) {
500
- if (typeof callback === "function") {
501
- __classPrivateFieldGet(this, _subscribers)[event].push(callback);
502
- }
503
- // @TODO: Maybe throw for invalid callbacks?
504
- }
505
- /**
506
- * Unsubscribe from an event, remove an event listener.
507
- *
508
- * @remarks If the same callback was subscribed more than once **all** occurences will be removed.
509
- *
510
- * @param event - Event name.
511
- * @param callback - Callback method.
512
- */
513
- off(event, callback) {
514
- __classPrivateFieldGet(this, _subscribers)[event] = __classPrivateFieldGet(this, _subscribers)[event].filter((subscriber) => subscriber !== callback);
515
- }
516
- }
517
- _subscribers = new WeakMap();
470
+ /**
471
+ * Data stream
472
+ *
473
+ * @remarks
474
+ * [[DataStream]] offers an always up to date stream of items from a [[DataSet]] or [[DataView]].
475
+ * That means that the stream is evaluated at the time of iteration, conversion to another data type or when [[cache]] is called, not when the [[DataStream]] was created.
476
+ * Multiple invocations of for example [[toItemArray]] may yield different results (if the data source like for example [[DataSet]] gets modified).
477
+ * @typeParam Item - The item type this stream is going to work with.
478
+ */
479
+ class DataStream {
480
+ /**
481
+ * Create a new data stream.
482
+ *
483
+ * @param pairs - The id, item pairs.
484
+ */
485
+ constructor(pairs) {
486
+ this._pairs = pairs;
487
+ }
488
+ /**
489
+ * Return an iterable of key, value pairs for every entry in the stream.
490
+ */
491
+ *[Symbol.iterator]() {
492
+ for (const [id, item] of this._pairs) {
493
+ yield [id, item];
494
+ }
495
+ }
496
+ /**
497
+ * Return an iterable of key, value pairs for every entry in the stream.
498
+ */
499
+ *entries() {
500
+ for (const [id, item] of this._pairs) {
501
+ yield [id, item];
502
+ }
503
+ }
504
+ /**
505
+ * Return an iterable of keys in the stream.
506
+ */
507
+ *keys() {
508
+ for (const [id] of this._pairs) {
509
+ yield id;
510
+ }
511
+ }
512
+ /**
513
+ * Return an iterable of values in the stream.
514
+ */
515
+ *values() {
516
+ for (const [, item] of this._pairs) {
517
+ yield item;
518
+ }
519
+ }
520
+ /**
521
+ * Return an array containing all the ids in this stream.
522
+ *
523
+ * @remarks
524
+ * The array may contain duplicities.
525
+ * @returns The array with all ids from this stream.
526
+ */
527
+ toIdArray() {
528
+ return [...this._pairs].map((pair) => pair[0]);
529
+ }
530
+ /**
531
+ * Return an array containing all the items in this stream.
532
+ *
533
+ * @remarks
534
+ * The array may contain duplicities.
535
+ * @returns The array with all items from this stream.
536
+ */
537
+ toItemArray() {
538
+ return [...this._pairs].map((pair) => pair[1]);
539
+ }
540
+ /**
541
+ * Return an array containing all the entries in this stream.
542
+ *
543
+ * @remarks
544
+ * The array may contain duplicities.
545
+ * @returns The array with all entries from this stream.
546
+ */
547
+ toEntryArray() {
548
+ return [...this._pairs];
549
+ }
550
+ /**
551
+ * Return an object map containing all the items in this stream accessible by ids.
552
+ *
553
+ * @remarks
554
+ * In case of duplicate ids (coerced to string so `7 == '7'`) the last encoutered appears in the returned object.
555
+ * @returns The object map of all id → item pairs from this stream.
556
+ */
557
+ toObjectMap() {
558
+ const map = Object.create(null);
559
+ for (const [id, item] of this._pairs) {
560
+ map[id] = item;
561
+ }
562
+ return map;
563
+ }
564
+ /**
565
+ * Return a map containing all the items in this stream accessible by ids.
566
+ *
567
+ * @returns The map of all id → item pairs from this stream.
568
+ */
569
+ toMap() {
570
+ return new Map(this._pairs);
571
+ }
572
+ /**
573
+ * Return a set containing all the (unique) ids in this stream.
574
+ *
575
+ * @returns The set of all ids from this stream.
576
+ */
577
+ toIdSet() {
578
+ return new Set(this.toIdArray());
579
+ }
580
+ /**
581
+ * Return a set containing all the (unique) items in this stream.
582
+ *
583
+ * @returns The set of all items from this stream.
584
+ */
585
+ toItemSet() {
586
+ return new Set(this.toItemArray());
587
+ }
588
+ /**
589
+ * Cache the items from this stream.
590
+ *
591
+ * @remarks
592
+ * This method allows for items to be fetched immediatelly and used (possibly multiple times) later.
593
+ * It can also be used to optimize performance as [[DataStream]] would otherwise reevaluate everything upon each iteration.
594
+ *
595
+ * ## Example
596
+ * ```javascript
597
+ * const ds = new DataSet([…])
598
+ *
599
+ * const cachedStream = ds.stream()
600
+ * .filter(…)
601
+ * .sort(…)
602
+ * .map(…)
603
+ * .cached(…) // Data are fetched, processed and cached here.
604
+ *
605
+ * ds.clear()
606
+ * chachedStream // Still has all the items.
607
+ * ```
608
+ * @returns A new [[DataStream]] with cached items (detached from the original [[DataSet]]).
609
+ */
610
+ cache() {
611
+ return new DataStream([...this._pairs]);
612
+ }
613
+ /**
614
+ * Get the distinct values of given property.
615
+ *
616
+ * @param callback - The function that picks and possibly converts the property.
617
+ * @typeParam T - The type of the distinct value.
618
+ * @returns A set of all distinct properties.
619
+ */
620
+ distinct(callback) {
621
+ const set = new Set();
622
+ for (const [id, item] of this._pairs) {
623
+ set.add(callback(item, id));
624
+ }
625
+ return set;
626
+ }
627
+ /**
628
+ * Filter the items of the stream.
629
+ *
630
+ * @param callback - The function that decides whether an item will be included.
631
+ * @returns A new data stream with the filtered items.
632
+ */
633
+ filter(callback) {
634
+ const pairs = this._pairs;
635
+ return new DataStream({
636
+ *[Symbol.iterator]() {
637
+ for (const [id, item] of pairs) {
638
+ if (callback(item, id)) {
639
+ yield [id, item];
640
+ }
641
+ }
642
+ },
643
+ });
644
+ }
645
+ /**
646
+ * Execute a callback for each item of the stream.
647
+ *
648
+ * @param callback - The function that will be invoked for each item.
649
+ */
650
+ forEach(callback) {
651
+ for (const [id, item] of this._pairs) {
652
+ callback(item, id);
653
+ }
654
+ }
655
+ /**
656
+ * Map the items into a different type.
657
+ *
658
+ * @param callback - The function that does the conversion.
659
+ * @typeParam Mapped - The type of the item after mapping.
660
+ * @returns A new data stream with the mapped items.
661
+ */
662
+ map(callback) {
663
+ const pairs = this._pairs;
664
+ return new DataStream({
665
+ *[Symbol.iterator]() {
666
+ for (const [id, item] of pairs) {
667
+ yield [id, callback(item, id)];
668
+ }
669
+ },
670
+ });
671
+ }
672
+ /**
673
+ * Get the item with the maximum value of given property.
674
+ *
675
+ * @param callback - The function that picks and possibly converts the property.
676
+ * @returns The item with the maximum if found otherwise null.
677
+ */
678
+ max(callback) {
679
+ const iter = this._pairs[Symbol.iterator]();
680
+ let curr = iter.next();
681
+ if (curr.done) {
682
+ return null;
683
+ }
684
+ let maxItem = curr.value[1];
685
+ let maxValue = callback(curr.value[1], curr.value[0]);
686
+ while (!(curr = iter.next()).done) {
687
+ const [id, item] = curr.value;
688
+ const value = callback(item, id);
689
+ if (value > maxValue) {
690
+ maxValue = value;
691
+ maxItem = item;
692
+ }
693
+ }
694
+ return maxItem;
695
+ }
696
+ /**
697
+ * Get the item with the minimum value of given property.
698
+ *
699
+ * @param callback - The function that picks and possibly converts the property.
700
+ * @returns The item with the minimum if found otherwise null.
701
+ */
702
+ min(callback) {
703
+ const iter = this._pairs[Symbol.iterator]();
704
+ let curr = iter.next();
705
+ if (curr.done) {
706
+ return null;
707
+ }
708
+ let minItem = curr.value[1];
709
+ let minValue = callback(curr.value[1], curr.value[0]);
710
+ while (!(curr = iter.next()).done) {
711
+ const [id, item] = curr.value;
712
+ const value = callback(item, id);
713
+ if (value < minValue) {
714
+ minValue = value;
715
+ minItem = item;
716
+ }
717
+ }
718
+ return minItem;
719
+ }
720
+ /**
721
+ * Reduce the items into a single value.
722
+ *
723
+ * @param callback - The function that does the reduction.
724
+ * @param accumulator - The initial value of the accumulator.
725
+ * @typeParam T - The type of the accumulated value.
726
+ * @returns The reduced value.
727
+ */
728
+ reduce(callback, accumulator) {
729
+ for (const [id, item] of this._pairs) {
730
+ accumulator = callback(accumulator, item, id);
731
+ }
732
+ return accumulator;
733
+ }
734
+ /**
735
+ * Sort the items.
736
+ *
737
+ * @param callback - Item comparator.
738
+ * @returns A new stream with sorted items.
739
+ */
740
+ sort(callback) {
741
+ return new DataStream({
742
+ [Symbol.iterator]: () => [...this._pairs]
743
+ .sort(([idA, itemA], [idB, itemB]) => callback(itemA, itemB, idA, idB))[Symbol.iterator](),
744
+ });
745
+ }
746
+ }
518
747
 
519
- var _pairs;
520
- /**
521
- * Data stream
522
- *
523
- * @remarks
524
- * [[DataStream]] offers an always up to date stream of items from a [[DataSet]] or [[DataView]].
525
- * That means that the stream is evaluated at the time of iteration, conversion to another data type or when [[cache]] is called, not when the [[DataStream]] was created.
526
- * Multiple invocations of for example [[toItemArray]] may yield different results (if the data source like for example [[DataSet]] gets modified).
527
- *
528
- * @typeParam Item - The item type this stream is going to work with.
529
- */
530
- class DataStream {
531
- /**
532
- * Create a new data stream.
533
- *
534
- * @param pairs - The id, item pairs.
535
- */
536
- constructor(pairs) {
537
- _pairs.set(this, void 0);
538
- __classPrivateFieldSet(this, _pairs, pairs);
539
- }
540
- /**
541
- * Return an iterable of key, value pairs for every entry in the stream.
542
- */
543
- *[(_pairs = new WeakMap(), Symbol.iterator)]() {
544
- for (const [id, item] of __classPrivateFieldGet(this, _pairs)) {
545
- yield [id, item];
546
- }
547
- }
548
- /**
549
- * Return an iterable of key, value pairs for every entry in the stream.
550
- */
551
- *entries() {
552
- for (const [id, item] of __classPrivateFieldGet(this, _pairs)) {
553
- yield [id, item];
554
- }
555
- }
556
- /**
557
- * Return an iterable of keys in the stream.
558
- */
559
- *keys() {
560
- for (const [id] of __classPrivateFieldGet(this, _pairs)) {
561
- yield id;
562
- }
563
- }
564
- /**
565
- * Return an iterable of values in the stream.
566
- */
567
- *values() {
568
- for (const [, item] of __classPrivateFieldGet(this, _pairs)) {
569
- yield item;
570
- }
571
- }
572
- /**
573
- * Return an array containing all the ids in this stream.
574
- *
575
- * @remarks
576
- * The array may contain duplicities.
577
- *
578
- * @returns The array with all ids from this stream.
579
- */
580
- toIdArray() {
581
- return [...__classPrivateFieldGet(this, _pairs)].map((pair) => pair[0]);
582
- }
583
- /**
584
- * Return an array containing all the items in this stream.
585
- *
586
- * @remarks
587
- * The array may contain duplicities.
588
- *
589
- * @returns The array with all items from this stream.
590
- */
591
- toItemArray() {
592
- return [...__classPrivateFieldGet(this, _pairs)].map((pair) => pair[1]);
593
- }
594
- /**
595
- * Return an array containing all the entries in this stream.
596
- *
597
- * @remarks
598
- * The array may contain duplicities.
599
- *
600
- * @returns The array with all entries from this stream.
601
- */
602
- toEntryArray() {
603
- return [...__classPrivateFieldGet(this, _pairs)];
604
- }
605
- /**
606
- * Return an object map containing all the items in this stream accessible by ids.
607
- *
608
- * @remarks
609
- * In case of duplicate ids (coerced to string so `7 == '7'`) the last encoutered appears in the returned object.
610
- *
611
- * @returns The object map of all id → item pairs from this stream.
612
- */
613
- toObjectMap() {
614
- const map = Object.create(null);
615
- for (const [id, item] of __classPrivateFieldGet(this, _pairs)) {
616
- map[id] = item;
617
- }
618
- return map;
619
- }
620
- /**
621
- * Return a map containing all the items in this stream accessible by ids.
622
- *
623
- * @returns The map of all id → item pairs from this stream.
624
- */
625
- toMap() {
626
- return new Map(__classPrivateFieldGet(this, _pairs));
627
- }
628
- /**
629
- * Return a set containing all the (unique) ids in this stream.
630
- *
631
- * @returns The set of all ids from this stream.
632
- */
633
- toIdSet() {
634
- return new Set(this.toIdArray());
635
- }
636
- /**
637
- * Return a set containing all the (unique) items in this stream.
638
- *
639
- * @returns The set of all items from this stream.
640
- */
641
- toItemSet() {
642
- return new Set(this.toItemArray());
643
- }
644
- /**
645
- * Cache the items from this stream.
646
- *
647
- * @remarks
648
- * This method allows for items to be fetched immediatelly and used (possibly multiple times) later.
649
- * It can also be used to optimize performance as [[DataStream]] would otherwise reevaluate everything upon each iteration.
650
- *
651
- * ## Example
652
- * ```javascript
653
- * const ds = new DataSet([…])
654
- *
655
- * const cachedStream = ds.stream()
656
- * .filter(…)
657
- * .sort(…)
658
- * .map(…)
659
- * .cached(…) // Data are fetched, processed and cached here.
660
- *
661
- * ds.clear()
662
- * chachedStream // Still has all the items.
663
- * ```
664
- *
665
- * @returns A new [[DataStream]] with cached items (detached from the original [[DataSet]]).
666
- */
667
- cache() {
668
- return new DataStream([...__classPrivateFieldGet(this, _pairs)]);
669
- }
670
- /**
671
- * Get the distinct values of given property.
672
- *
673
- * @param callback - The function that picks and possibly converts the property.
674
- *
675
- * @typeParam T - The type of the distinct value.
676
- *
677
- * @returns A set of all distinct properties.
678
- */
679
- distinct(callback) {
680
- const set = new Set();
681
- for (const [id, item] of __classPrivateFieldGet(this, _pairs)) {
682
- set.add(callback(item, id));
683
- }
684
- return set;
685
- }
686
- /**
687
- * Filter the items of the stream.
688
- *
689
- * @param callback - The function that decides whether an item will be included.
690
- *
691
- * @returns A new data stream with the filtered items.
692
- */
693
- filter(callback) {
694
- const pairs = __classPrivateFieldGet(this, _pairs);
695
- return new DataStream({
696
- *[Symbol.iterator]() {
697
- for (const [id, item] of pairs) {
698
- if (callback(item, id)) {
699
- yield [id, item];
700
- }
701
- }
702
- },
703
- });
704
- }
705
- /**
706
- * Execute a callback for each item of the stream.
707
- *
708
- * @param callback - The function that will be invoked for each item.
709
- */
710
- forEach(callback) {
711
- for (const [id, item] of __classPrivateFieldGet(this, _pairs)) {
712
- callback(item, id);
713
- }
714
- }
715
- /**
716
- * Map the items into a different type.
717
- *
718
- * @param callback - The function that does the conversion.
719
- *
720
- * @typeParam Mapped - The type of the item after mapping.
721
- *
722
- * @returns A new data stream with the mapped items.
723
- */
724
- map(callback) {
725
- const pairs = __classPrivateFieldGet(this, _pairs);
726
- return new DataStream({
727
- *[Symbol.iterator]() {
728
- for (const [id, item] of pairs) {
729
- yield [id, callback(item, id)];
730
- }
731
- },
732
- });
733
- }
734
- /**
735
- * Get the item with the maximum value of given property.
736
- *
737
- * @param callback - The function that picks and possibly converts the property.
738
- *
739
- * @returns The item with the maximum if found otherwise null.
740
- */
741
- max(callback) {
742
- const iter = __classPrivateFieldGet(this, _pairs)[Symbol.iterator]();
743
- let curr = iter.next();
744
- if (curr.done) {
745
- return null;
746
- }
747
- let maxItem = curr.value[1];
748
- let maxValue = callback(curr.value[1], curr.value[0]);
749
- while (!(curr = iter.next()).done) {
750
- const [id, item] = curr.value;
751
- const value = callback(item, id);
752
- if (value > maxValue) {
753
- maxValue = value;
754
- maxItem = item;
755
- }
756
- }
757
- return maxItem;
758
- }
759
- /**
760
- * Get the item with the minimum value of given property.
761
- *
762
- * @param callback - The function that picks and possibly converts the property.
763
- *
764
- * @returns The item with the minimum if found otherwise null.
765
- */
766
- min(callback) {
767
- const iter = __classPrivateFieldGet(this, _pairs)[Symbol.iterator]();
768
- let curr = iter.next();
769
- if (curr.done) {
770
- return null;
771
- }
772
- let minItem = curr.value[1];
773
- let minValue = callback(curr.value[1], curr.value[0]);
774
- while (!(curr = iter.next()).done) {
775
- const [id, item] = curr.value;
776
- const value = callback(item, id);
777
- if (value < minValue) {
778
- minValue = value;
779
- minItem = item;
780
- }
781
- }
782
- return minItem;
783
- }
784
- /**
785
- * Reduce the items into a single value.
786
- *
787
- * @param callback - The function that does the reduction.
788
- * @param accumulator - The initial value of the accumulator.
789
- *
790
- * @typeParam T - The type of the accumulated value.
791
- *
792
- * @returns The reduced value.
793
- */
794
- reduce(callback, accumulator) {
795
- for (const [id, item] of __classPrivateFieldGet(this, _pairs)) {
796
- accumulator = callback(accumulator, item, id);
797
- }
798
- return accumulator;
799
- }
800
- /**
801
- * Sort the items.
802
- *
803
- * @param callback - Item comparator.
804
- *
805
- * @returns A new stream with sorted items.
806
- */
807
- sort(callback) {
808
- return new DataStream({
809
- [Symbol.iterator]: () => [...__classPrivateFieldGet(this, _pairs)]
810
- .sort(([idA, itemA], [idB, itemB]) => callback(itemA, itemB, idA, idB))[Symbol.iterator](),
811
- });
812
- }
813
- }
748
+ /**
749
+ * Add an id to given item if it doesn't have one already.
750
+ *
751
+ * @remarks
752
+ * The item will be modified.
753
+ * @param item - The item that will have an id after a call to this function.
754
+ * @param idProp - The key of the id property.
755
+ * @typeParam Item - Item type that may or may not have an id.
756
+ * @typeParam IdProp - Name of the property that contains the id.
757
+ * @returns true
758
+ */
759
+ function ensureFullItem(item, idProp) {
760
+ if (item[idProp] == null) {
761
+ // generate an id
762
+ item[idProp] = uuid.v4();
763
+ }
764
+ return item;
765
+ }
766
+ /**
767
+ * # DataSet
768
+ *
769
+ * Vis.js comes with a flexible DataSet, which can be used to hold and
770
+ * manipulate unstructured data and listen for changes in the data. The DataSet
771
+ * is key/value based. Data items can be added, updated and removed from the
772
+ * DataSet, and one can subscribe to changes in the DataSet. The data in the
773
+ * DataSet can be filtered and ordered. Data can be normalized when appending it
774
+ * to the DataSet as well.
775
+ *
776
+ * ## Example
777
+ *
778
+ * The following example shows how to use a DataSet.
779
+ *
780
+ * ```javascript
781
+ * // create a DataSet
782
+ * var options = {};
783
+ * var data = new vis.DataSet(options);
784
+ *
785
+ * // add items
786
+ * // note that the data items can contain different properties and data formats
787
+ * data.add([
788
+ * {id: 1, text: 'item 1', date: new Date(2013, 6, 20), group: 1, first: true},
789
+ * {id: 2, text: 'item 2', date: '2013-06-23', group: 2},
790
+ * {id: 3, text: 'item 3', date: '2013-06-25', group: 2},
791
+ * {id: 4, text: 'item 4'}
792
+ * ]);
793
+ *
794
+ * // subscribe to any change in the DataSet
795
+ * data.on('*', function (event, properties, senderId) {
796
+ * console.log('event', event, properties);
797
+ * });
798
+ *
799
+ * // update an existing item
800
+ * data.update({id: 2, group: 1});
801
+ *
802
+ * // remove an item
803
+ * data.remove(4);
804
+ *
805
+ * // get all ids
806
+ * var ids = data.getIds();
807
+ * console.log('ids', ids);
808
+ *
809
+ * // get a specific item
810
+ * var item1 = data.get(1);
811
+ * console.log('item1', item1);
812
+ *
813
+ * // retrieve a filtered subset of the data
814
+ * var items = data.get({
815
+ * filter: function (item) {
816
+ * return item.group == 1;
817
+ * }
818
+ * });
819
+ * console.log('filtered items', items);
820
+ * ```
821
+ *
822
+ * @typeParam Item - Item type that may or may not have an id.
823
+ * @typeParam IdProp - Name of the property that contains the id.
824
+ */
825
+ class DataSet extends DataSetPart {
826
+ /**
827
+ * Construct a new DataSet.
828
+ *
829
+ * @param data - Initial data or options.
830
+ * @param options - Options (type error if data is also options).
831
+ */
832
+ constructor(data, options) {
833
+ super();
834
+ this._queue = null;
835
+ // correctly read optional arguments
836
+ if (data && !Array.isArray(data)) {
837
+ options = data;
838
+ data = [];
839
+ }
840
+ this._options = options || {};
841
+ this._data = new Map(); // map with data indexed by id
842
+ this.length = 0; // number of items in the DataSet
843
+ this._idProp = this._options.fieldId || "id"; // name of the field containing id
844
+ // add initial data when provided
845
+ if (data && data.length) {
846
+ this.add(data);
847
+ }
848
+ this.setOptions(options);
849
+ }
850
+ /** @inheritDoc */
851
+ get idProp() {
852
+ return this._idProp;
853
+ }
854
+ /**
855
+ * Set new options.
856
+ *
857
+ * @param options - The new options.
858
+ */
859
+ setOptions(options) {
860
+ if (options && options.queue !== undefined) {
861
+ if (options.queue === false) {
862
+ // delete queue if loaded
863
+ if (this._queue) {
864
+ this._queue.destroy();
865
+ this._queue = null;
866
+ }
867
+ }
868
+ else {
869
+ // create queue and update its options
870
+ if (!this._queue) {
871
+ this._queue = Queue.extend(this, {
872
+ replace: ["add", "update", "remove"],
873
+ });
874
+ }
875
+ if (options.queue && typeof options.queue === "object") {
876
+ this._queue.setOptions(options.queue);
877
+ }
878
+ }
879
+ }
880
+ }
881
+ /**
882
+ * Add a data item or an array with items.
883
+ *
884
+ * After the items are added to the DataSet, the DataSet will trigger an event `add`. When a `senderId` is provided, this id will be passed with the triggered event to all subscribers.
885
+ *
886
+ * ## Example
887
+ *
888
+ * ```javascript
889
+ * // create a DataSet
890
+ * const data = new vis.DataSet()
891
+ *
892
+ * // add items
893
+ * const ids = data.add([
894
+ * { id: 1, text: 'item 1' },
895
+ * { id: 2, text: 'item 2' },
896
+ * { text: 'item without an id' }
897
+ * ])
898
+ *
899
+ * console.log(ids) // [1, 2, '<UUIDv4>']
900
+ * ```
901
+ *
902
+ * @param data - Items to be added (ids will be generated if missing).
903
+ * @param senderId - Sender id.
904
+ * @returns addedIds - Array with the ids (generated if not present) of the added items.
905
+ * @throws When an item with the same id as any of the added items already exists.
906
+ */
907
+ add(data, senderId) {
908
+ const addedIds = [];
909
+ let id;
910
+ if (Array.isArray(data)) {
911
+ // Array
912
+ const idsToAdd = data.map((d) => d[this._idProp]);
913
+ if (idsToAdd.some((id) => this._data.has(id))) {
914
+ throw new Error("A duplicate id was found in the parameter array.");
915
+ }
916
+ for (let i = 0, len = data.length; i < len; i++) {
917
+ id = this._addItem(data[i]);
918
+ addedIds.push(id);
919
+ }
920
+ }
921
+ else if (data && typeof data === "object") {
922
+ // Single item
923
+ id = this._addItem(data);
924
+ addedIds.push(id);
925
+ }
926
+ else {
927
+ throw new Error("Unknown dataType");
928
+ }
929
+ if (addedIds.length) {
930
+ this._trigger("add", { items: addedIds }, senderId);
931
+ }
932
+ return addedIds;
933
+ }
934
+ /**
935
+ * Update existing items. When an item does not exist, it will be created.
936
+ *
937
+ * @remarks
938
+ * The provided properties will be merged in the existing item. When an item does not exist, it will be created.
939
+ *
940
+ * After the items are updated, the DataSet will trigger an event `add` for the added items, and an event `update`. When a `senderId` is provided, this id will be passed with the triggered event to all subscribers.
941
+ *
942
+ * ## Example
943
+ *
944
+ * ```javascript
945
+ * // create a DataSet
946
+ * const data = new vis.DataSet([
947
+ * { id: 1, text: 'item 1' },
948
+ * { id: 2, text: 'item 2' },
949
+ * { id: 3, text: 'item 3' }
950
+ * ])
951
+ *
952
+ * // update items
953
+ * const ids = data.update([
954
+ * { id: 2, text: 'item 2 (updated)' },
955
+ * { id: 4, text: 'item 4 (new)' }
956
+ * ])
957
+ *
958
+ * console.log(ids) // [2, 4]
959
+ * ```
960
+ *
961
+ * ## Warning for TypeScript users
962
+ * This method may introduce partial items into the data set. Use add or updateOnly instead for better type safety.
963
+ * @param data - Items to be updated (if the id is already present) or added (if the id is missing).
964
+ * @param senderId - Sender id.
965
+ * @returns updatedIds - The ids of the added (these may be newly generated if there was no id in the item from the data) or updated items.
966
+ * @throws When the supplied data is neither an item nor an array of items.
967
+ */
968
+ update(data, senderId) {
969
+ const addedIds = [];
970
+ const updatedIds = [];
971
+ const oldData = [];
972
+ const updatedData = [];
973
+ const idProp = this._idProp;
974
+ const addOrUpdate = (item) => {
975
+ const origId = item[idProp];
976
+ if (origId != null && this._data.has(origId)) {
977
+ const fullItem = item; // it has an id, therefore it is a fullitem
978
+ const oldItem = Object.assign({}, this._data.get(origId));
979
+ // update item
980
+ const id = this._updateItem(fullItem);
981
+ updatedIds.push(id);
982
+ updatedData.push(fullItem);
983
+ oldData.push(oldItem);
984
+ }
985
+ else {
986
+ // add new item
987
+ const id = this._addItem(item);
988
+ addedIds.push(id);
989
+ }
990
+ };
991
+ if (Array.isArray(data)) {
992
+ // Array
993
+ for (let i = 0, len = data.length; i < len; i++) {
994
+ if (data[i] && typeof data[i] === "object") {
995
+ addOrUpdate(data[i]);
996
+ }
997
+ else {
998
+ console.warn("Ignoring input item, which is not an object at index " + i);
999
+ }
1000
+ }
1001
+ }
1002
+ else if (data && typeof data === "object") {
1003
+ // Single item
1004
+ addOrUpdate(data);
1005
+ }
1006
+ else {
1007
+ throw new Error("Unknown dataType");
1008
+ }
1009
+ if (addedIds.length) {
1010
+ this._trigger("add", { items: addedIds }, senderId);
1011
+ }
1012
+ if (updatedIds.length) {
1013
+ const props = { items: updatedIds, oldData: oldData, data: updatedData };
1014
+ // TODO: remove deprecated property 'data' some day
1015
+ //Object.defineProperty(props, 'data', {
1016
+ // 'get': (function() {
1017
+ // console.warn('Property data is deprecated. Use DataSet.get(ids) to retrieve the new data, use the oldData property on this object to get the old data');
1018
+ // return updatedData;
1019
+ // }).bind(this)
1020
+ //});
1021
+ this._trigger("update", props, senderId);
1022
+ }
1023
+ return addedIds.concat(updatedIds);
1024
+ }
1025
+ /**
1026
+ * Update existing items. When an item does not exist, an error will be thrown.
1027
+ *
1028
+ * @remarks
1029
+ * The provided properties will be deeply merged into the existing item.
1030
+ * When an item does not exist (id not present in the data set or absent), an error will be thrown and nothing will be changed.
1031
+ *
1032
+ * After the items are updated, the DataSet will trigger an event `update`.
1033
+ * When a `senderId` is provided, this id will be passed with the triggered event to all subscribers.
1034
+ *
1035
+ * ## Example
1036
+ *
1037
+ * ```javascript
1038
+ * // create a DataSet
1039
+ * const data = new vis.DataSet([
1040
+ * { id: 1, text: 'item 1' },
1041
+ * { id: 2, text: 'item 2' },
1042
+ * { id: 3, text: 'item 3' },
1043
+ * ])
1044
+ *
1045
+ * // update items
1046
+ * const ids = data.update([
1047
+ * { id: 2, text: 'item 2 (updated)' }, // works
1048
+ * // { id: 4, text: 'item 4 (new)' }, // would throw
1049
+ * // { text: 'item 4 (new)' }, // would also throw
1050
+ * ])
1051
+ *
1052
+ * console.log(ids) // [2]
1053
+ * ```
1054
+ * @param data - Updates (the id and optionally other props) to the items in this data set.
1055
+ * @param senderId - Sender id.
1056
+ * @returns updatedIds - The ids of the updated items.
1057
+ * @throws When the supplied data is neither an item nor an array of items, when the ids are missing.
1058
+ */
1059
+ updateOnly(data, senderId) {
1060
+ if (!Array.isArray(data)) {
1061
+ data = [data];
1062
+ }
1063
+ const updateEventData = data
1064
+ .map((update) => {
1065
+ const oldData = this._data.get(update[this._idProp]);
1066
+ if (oldData == null) {
1067
+ throw new Error("Updating non-existent items is not allowed.");
1068
+ }
1069
+ return { oldData, update };
1070
+ })
1071
+ .map(({ oldData, update }) => {
1072
+ const id = oldData[this._idProp];
1073
+ const updatedData = esnext.pureDeepObjectAssign(oldData, update);
1074
+ this._data.set(id, updatedData);
1075
+ return {
1076
+ id,
1077
+ oldData: oldData,
1078
+ updatedData,
1079
+ };
1080
+ });
1081
+ if (updateEventData.length) {
1082
+ const props = {
1083
+ items: updateEventData.map((value) => value.id),
1084
+ oldData: updateEventData.map((value) => value.oldData),
1085
+ data: updateEventData.map((value) => value.updatedData),
1086
+ };
1087
+ // TODO: remove deprecated property 'data' some day
1088
+ //Object.defineProperty(props, 'data', {
1089
+ // 'get': (function() {
1090
+ // console.warn('Property data is deprecated. Use DataSet.get(ids) to retrieve the new data, use the oldData property on this object to get the old data');
1091
+ // return updatedData;
1092
+ // }).bind(this)
1093
+ //});
1094
+ this._trigger("update", props, senderId);
1095
+ return props.items;
1096
+ }
1097
+ else {
1098
+ return [];
1099
+ }
1100
+ }
1101
+ /** @inheritDoc */
1102
+ get(first, second) {
1103
+ // @TODO: Woudn't it be better to split this into multiple methods?
1104
+ // parse the arguments
1105
+ let id = undefined;
1106
+ let ids = undefined;
1107
+ let options = undefined;
1108
+ if (isId(first)) {
1109
+ // get(id [, options])
1110
+ id = first;
1111
+ options = second;
1112
+ }
1113
+ else if (Array.isArray(first)) {
1114
+ // get(ids [, options])
1115
+ ids = first;
1116
+ options = second;
1117
+ }
1118
+ else {
1119
+ // get([, options])
1120
+ options = first;
1121
+ }
1122
+ // determine the return type
1123
+ const returnType = options && options.returnType === "Object" ? "Object" : "Array";
1124
+ // @TODO: WTF is this? Or am I missing something?
1125
+ // var returnType
1126
+ // if (options && options.returnType) {
1127
+ // var allowedValues = ['Array', 'Object']
1128
+ // returnType =
1129
+ // allowedValues.indexOf(options.returnType) == -1
1130
+ // ? 'Array'
1131
+ // : options.returnType
1132
+ // } else {
1133
+ // returnType = 'Array'
1134
+ // }
1135
+ // build options
1136
+ const filter = options && options.filter;
1137
+ const items = [];
1138
+ let item = undefined;
1139
+ let itemIds = undefined;
1140
+ let itemId = undefined;
1141
+ // convert items
1142
+ if (id != null) {
1143
+ // return a single item
1144
+ item = this._data.get(id);
1145
+ if (item && filter && !filter(item)) {
1146
+ item = undefined;
1147
+ }
1148
+ }
1149
+ else if (ids != null) {
1150
+ // return a subset of items
1151
+ for (let i = 0, len = ids.length; i < len; i++) {
1152
+ item = this._data.get(ids[i]);
1153
+ if (item != null && (!filter || filter(item))) {
1154
+ items.push(item);
1155
+ }
1156
+ }
1157
+ }
1158
+ else {
1159
+ // return all items
1160
+ itemIds = [...this._data.keys()];
1161
+ for (let i = 0, len = itemIds.length; i < len; i++) {
1162
+ itemId = itemIds[i];
1163
+ item = this._data.get(itemId);
1164
+ if (item != null && (!filter || filter(item))) {
1165
+ items.push(item);
1166
+ }
1167
+ }
1168
+ }
1169
+ // order the results
1170
+ if (options && options.order && id == undefined) {
1171
+ this._sort(items, options.order);
1172
+ }
1173
+ // filter fields of the items
1174
+ if (options && options.fields) {
1175
+ const fields = options.fields;
1176
+ if (id != undefined && item != null) {
1177
+ item = this._filterFields(item, fields);
1178
+ }
1179
+ else {
1180
+ for (let i = 0, len = items.length; i < len; i++) {
1181
+ items[i] = this._filterFields(items[i], fields);
1182
+ }
1183
+ }
1184
+ }
1185
+ // return the results
1186
+ if (returnType == "Object") {
1187
+ const result = {};
1188
+ for (let i = 0, len = items.length; i < len; i++) {
1189
+ const resultant = items[i];
1190
+ // @TODO: Shoudn't this be this._fieldId?
1191
+ // result[resultant.id] = resultant
1192
+ const id = resultant[this._idProp];
1193
+ result[id] = resultant;
1194
+ }
1195
+ return result;
1196
+ }
1197
+ else {
1198
+ if (id != null) {
1199
+ // a single item
1200
+ return item ?? null;
1201
+ }
1202
+ else {
1203
+ // just return our array
1204
+ return items;
1205
+ }
1206
+ }
1207
+ }
1208
+ /** @inheritDoc */
1209
+ getIds(options) {
1210
+ const data = this._data;
1211
+ const filter = options && options.filter;
1212
+ const order = options && options.order;
1213
+ const itemIds = [...data.keys()];
1214
+ const ids = [];
1215
+ if (filter) {
1216
+ // get filtered items
1217
+ if (order) {
1218
+ // create ordered list
1219
+ const items = [];
1220
+ for (let i = 0, len = itemIds.length; i < len; i++) {
1221
+ const id = itemIds[i];
1222
+ const item = this._data.get(id);
1223
+ if (item != null && filter(item)) {
1224
+ items.push(item);
1225
+ }
1226
+ }
1227
+ this._sort(items, order);
1228
+ for (let i = 0, len = items.length; i < len; i++) {
1229
+ ids.push(items[i][this._idProp]);
1230
+ }
1231
+ }
1232
+ else {
1233
+ // create unordered list
1234
+ for (let i = 0, len = itemIds.length; i < len; i++) {
1235
+ const id = itemIds[i];
1236
+ const item = this._data.get(id);
1237
+ if (item != null && filter(item)) {
1238
+ ids.push(item[this._idProp]);
1239
+ }
1240
+ }
1241
+ }
1242
+ }
1243
+ else {
1244
+ // get all items
1245
+ if (order) {
1246
+ // create an ordered list
1247
+ const items = [];
1248
+ for (let i = 0, len = itemIds.length; i < len; i++) {
1249
+ const id = itemIds[i];
1250
+ items.push(data.get(id));
1251
+ }
1252
+ this._sort(items, order);
1253
+ for (let i = 0, len = items.length; i < len; i++) {
1254
+ ids.push(items[i][this._idProp]);
1255
+ }
1256
+ }
1257
+ else {
1258
+ // create unordered list
1259
+ for (let i = 0, len = itemIds.length; i < len; i++) {
1260
+ const id = itemIds[i];
1261
+ const item = data.get(id);
1262
+ if (item != null) {
1263
+ ids.push(item[this._idProp]);
1264
+ }
1265
+ }
1266
+ }
1267
+ }
1268
+ return ids;
1269
+ }
1270
+ /** @inheritDoc */
1271
+ getDataSet() {
1272
+ return this;
1273
+ }
1274
+ /** @inheritDoc */
1275
+ forEach(callback, options) {
1276
+ const filter = options && options.filter;
1277
+ const data = this._data;
1278
+ const itemIds = [...data.keys()];
1279
+ if (options && options.order) {
1280
+ // execute forEach on ordered list
1281
+ const items = this.get(options);
1282
+ for (let i = 0, len = items.length; i < len; i++) {
1283
+ const item = items[i];
1284
+ const id = item[this._idProp];
1285
+ callback(item, id);
1286
+ }
1287
+ }
1288
+ else {
1289
+ // unordered
1290
+ for (let i = 0, len = itemIds.length; i < len; i++) {
1291
+ const id = itemIds[i];
1292
+ const item = this._data.get(id);
1293
+ if (item != null && (!filter || filter(item))) {
1294
+ callback(item, id);
1295
+ }
1296
+ }
1297
+ }
1298
+ }
1299
+ /** @inheritDoc */
1300
+ map(callback, options) {
1301
+ const filter = options && options.filter;
1302
+ const mappedItems = [];
1303
+ const data = this._data;
1304
+ const itemIds = [...data.keys()];
1305
+ // convert and filter items
1306
+ for (let i = 0, len = itemIds.length; i < len; i++) {
1307
+ const id = itemIds[i];
1308
+ const item = this._data.get(id);
1309
+ if (item != null && (!filter || filter(item))) {
1310
+ mappedItems.push(callback(item, id));
1311
+ }
1312
+ }
1313
+ // order items
1314
+ if (options && options.order) {
1315
+ this._sort(mappedItems, options.order);
1316
+ }
1317
+ return mappedItems;
1318
+ }
1319
+ /**
1320
+ * Filter the fields of an item.
1321
+ *
1322
+ * @param item - The item whose fields should be filtered.
1323
+ * @param fields - The names of the fields that will be kept.
1324
+ * @typeParam K - Field name type.
1325
+ * @returns The item without any additional fields.
1326
+ */
1327
+ _filterFields(item, fields) {
1328
+ if (!item) {
1329
+ // item is null
1330
+ return item;
1331
+ }
1332
+ return (Array.isArray(fields)
1333
+ ? // Use the supplied array
1334
+ fields
1335
+ : // Use the keys of the supplied object
1336
+ Object.keys(fields)).reduce((filteredItem, field) => {
1337
+ filteredItem[field] = item[field];
1338
+ return filteredItem;
1339
+ }, {});
1340
+ }
1341
+ /**
1342
+ * Sort the provided array with items.
1343
+ *
1344
+ * @param items - Items to be sorted in place.
1345
+ * @param order - A field name or custom sort function.
1346
+ * @typeParam T - The type of the items in the items array.
1347
+ */
1348
+ _sort(items, order) {
1349
+ if (typeof order === "string") {
1350
+ // order by provided field name
1351
+ const name = order; // field name
1352
+ items.sort((a, b) => {
1353
+ // @TODO: How to treat missing properties?
1354
+ const av = a[name];
1355
+ const bv = b[name];
1356
+ return av > bv ? 1 : av < bv ? -1 : 0;
1357
+ });
1358
+ }
1359
+ else if (typeof order === "function") {
1360
+ // order by sort function
1361
+ items.sort(order);
1362
+ }
1363
+ else {
1364
+ // TODO: extend order by an Object {field:string, direction:string}
1365
+ // where direction can be 'asc' or 'desc'
1366
+ throw new TypeError("Order must be a function or a string");
1367
+ }
1368
+ }
1369
+ /**
1370
+ * Remove an item or multiple items by “reference” (only the id is used) or by id.
1371
+ *
1372
+ * The method ignores removal of non-existing items, and returns an array containing the ids of the items which are actually removed from the DataSet.
1373
+ *
1374
+ * After the items are removed, the DataSet will trigger an event `remove` for the removed items. When a `senderId` is provided, this id will be passed with the triggered event to all subscribers.
1375
+ *
1376
+ * ## Example
1377
+ * ```javascript
1378
+ * // create a DataSet
1379
+ * const data = new vis.DataSet([
1380
+ * { id: 1, text: 'item 1' },
1381
+ * { id: 2, text: 'item 2' },
1382
+ * { id: 3, text: 'item 3' }
1383
+ * ])
1384
+ *
1385
+ * // remove items
1386
+ * const ids = data.remove([2, { id: 3 }, 4])
1387
+ *
1388
+ * console.log(ids) // [2, 3]
1389
+ * ```
1390
+ *
1391
+ * @param id - One or more items or ids of items to be removed.
1392
+ * @param senderId - Sender id.
1393
+ * @returns The ids of the removed items.
1394
+ */
1395
+ remove(id, senderId) {
1396
+ const removedIds = [];
1397
+ const removedItems = [];
1398
+ // force everything to be an array for simplicity
1399
+ const ids = Array.isArray(id) ? id : [id];
1400
+ for (let i = 0, len = ids.length; i < len; i++) {
1401
+ const item = this._remove(ids[i]);
1402
+ if (item) {
1403
+ const itemId = item[this._idProp];
1404
+ if (itemId != null) {
1405
+ removedIds.push(itemId);
1406
+ removedItems.push(item);
1407
+ }
1408
+ }
1409
+ }
1410
+ if (removedIds.length) {
1411
+ this._trigger("remove", { items: removedIds, oldData: removedItems }, senderId);
1412
+ }
1413
+ return removedIds;
1414
+ }
1415
+ /**
1416
+ * Remove an item by its id or reference.
1417
+ *
1418
+ * @param id - Id of an item or the item itself.
1419
+ * @returns The removed item if removed, null otherwise.
1420
+ */
1421
+ _remove(id) {
1422
+ // @TODO: It origianlly returned the item although the docs say id.
1423
+ // The code expects the item, so probably an error in the docs.
1424
+ let ident;
1425
+ // confirm the id to use based on the args type
1426
+ if (isId(id)) {
1427
+ ident = id;
1428
+ }
1429
+ else if (id && typeof id === "object") {
1430
+ ident = id[this._idProp]; // look for the identifier field using ._idProp
1431
+ }
1432
+ // do the removing if the item is found
1433
+ if (ident != null && this._data.has(ident)) {
1434
+ const item = this._data.get(ident) || null;
1435
+ this._data.delete(ident);
1436
+ --this.length;
1437
+ return item;
1438
+ }
1439
+ return null;
1440
+ }
1441
+ /**
1442
+ * Clear the entire data set.
1443
+ *
1444
+ * After the items are removed, the [[DataSet]] will trigger an event `remove` for all removed items. When a `senderId` is provided, this id will be passed with the triggered event to all subscribers.
1445
+ *
1446
+ * @param senderId - Sender id.
1447
+ * @returns removedIds - The ids of all removed items.
1448
+ */
1449
+ clear(senderId) {
1450
+ const ids = [...this._data.keys()];
1451
+ const items = [];
1452
+ for (let i = 0, len = ids.length; i < len; i++) {
1453
+ items.push(this._data.get(ids[i]));
1454
+ }
1455
+ this._data.clear();
1456
+ this.length = 0;
1457
+ this._trigger("remove", { items: ids, oldData: items }, senderId);
1458
+ return ids;
1459
+ }
1460
+ /**
1461
+ * Find the item with maximum value of a specified field.
1462
+ *
1463
+ * @param field - Name of the property that should be searched for max value.
1464
+ * @returns Item containing max value, or null if no items.
1465
+ */
1466
+ max(field) {
1467
+ let max = null;
1468
+ let maxField = null;
1469
+ for (const item of this._data.values()) {
1470
+ const itemField = item[field];
1471
+ if (typeof itemField === "number" &&
1472
+ (maxField == null || itemField > maxField)) {
1473
+ max = item;
1474
+ maxField = itemField;
1475
+ }
1476
+ }
1477
+ return max || null;
1478
+ }
1479
+ /**
1480
+ * Find the item with minimum value of a specified field.
1481
+ *
1482
+ * @param field - Name of the property that should be searched for min value.
1483
+ * @returns Item containing min value, or null if no items.
1484
+ */
1485
+ min(field) {
1486
+ let min = null;
1487
+ let minField = null;
1488
+ for (const item of this._data.values()) {
1489
+ const itemField = item[field];
1490
+ if (typeof itemField === "number" &&
1491
+ (minField == null || itemField < minField)) {
1492
+ min = item;
1493
+ minField = itemField;
1494
+ }
1495
+ }
1496
+ return min || null;
1497
+ }
1498
+ /**
1499
+ * Find all distinct values of a specified field
1500
+ *
1501
+ * @param prop - The property name whose distinct values should be returned.
1502
+ * @returns Unordered array containing all distinct values. Items without specified property are ignored.
1503
+ */
1504
+ distinct(prop) {
1505
+ const data = this._data;
1506
+ const itemIds = [...data.keys()];
1507
+ const values = [];
1508
+ let count = 0;
1509
+ for (let i = 0, len = itemIds.length; i < len; i++) {
1510
+ const id = itemIds[i];
1511
+ const item = data.get(id);
1512
+ const value = item[prop];
1513
+ let exists = false;
1514
+ for (let j = 0; j < count; j++) {
1515
+ if (values[j] == value) {
1516
+ exists = true;
1517
+ break;
1518
+ }
1519
+ }
1520
+ if (!exists && value !== undefined) {
1521
+ values[count] = value;
1522
+ count++;
1523
+ }
1524
+ }
1525
+ return values;
1526
+ }
1527
+ /**
1528
+ * Add a single item. Will fail when an item with the same id already exists.
1529
+ *
1530
+ * @param item - A new item to be added.
1531
+ * @returns Added item's id. An id is generated when it is not present in the item.
1532
+ */
1533
+ _addItem(item) {
1534
+ const fullItem = ensureFullItem(item, this._idProp);
1535
+ const id = fullItem[this._idProp];
1536
+ // check whether this id is already taken
1537
+ if (this._data.has(id)) {
1538
+ // item already exists
1539
+ throw new Error("Cannot add item: item with id " + id + " already exists");
1540
+ }
1541
+ this._data.set(id, fullItem);
1542
+ ++this.length;
1543
+ return id;
1544
+ }
1545
+ /**
1546
+ * Update a single item: merge with existing item.
1547
+ * Will fail when the item has no id, or when there does not exist an item with the same id.
1548
+ *
1549
+ * @param update - The new item
1550
+ * @returns The id of the updated item.
1551
+ */
1552
+ _updateItem(update) {
1553
+ const id = update[this._idProp];
1554
+ if (id == null) {
1555
+ throw new Error("Cannot update item: item has no id (item: " +
1556
+ JSON.stringify(update) +
1557
+ ")");
1558
+ }
1559
+ const item = this._data.get(id);
1560
+ if (!item) {
1561
+ // item doesn't exist
1562
+ throw new Error("Cannot update item: no item with id " + id + " found");
1563
+ }
1564
+ this._data.set(id, { ...item, ...update });
1565
+ return id;
1566
+ }
1567
+ /** @inheritDoc */
1568
+ stream(ids) {
1569
+ if (ids) {
1570
+ const data = this._data;
1571
+ return new DataStream({
1572
+ *[Symbol.iterator]() {
1573
+ for (const id of ids) {
1574
+ const item = data.get(id);
1575
+ if (item != null) {
1576
+ yield [id, item];
1577
+ }
1578
+ }
1579
+ },
1580
+ });
1581
+ }
1582
+ else {
1583
+ return new DataStream({
1584
+ [Symbol.iterator]: this._data.entries.bind(this._data),
1585
+ });
1586
+ }
1587
+ }
1588
+ }
814
1589
 
815
- var _options, _data, _idProp, _queue$1;
816
- /**
817
- * Add an id to given item if it doesn't have one already.
818
- *
819
- * @remarks
820
- * The item will be modified.
821
- *
822
- * @param item - The item that will have an id after a call to this function.
823
- * @param idProp - The key of the id property.
824
- *
825
- * @typeParam Item - Item type that may or may not have an id.
826
- * @typeParam IdProp - Name of the property that contains the id.
827
- *
828
- * @returns true
829
- */
830
- function ensureFullItem(item, idProp) {
831
- if (item[idProp] == null) {
832
- // generate an id
833
- item[idProp] = uuid.v4();
834
- }
835
- return item;
836
- }
837
- /**
838
- * # DataSet
839
- *
840
- * Vis.js comes with a flexible DataSet, which can be used to hold and
841
- * manipulate unstructured data and listen for changes in the data. The DataSet
842
- * is key/value based. Data items can be added, updated and removed from the
843
- * DataSet, and one can subscribe to changes in the DataSet. The data in the
844
- * DataSet can be filtered and ordered. Data can be normalized when appending it
845
- * to the DataSet as well.
846
- *
847
- * ## Example
848
- *
849
- * The following example shows how to use a DataSet.
850
- *
851
- * ```javascript
852
- * // create a DataSet
853
- * var options = {};
854
- * var data = new vis.DataSet(options);
855
- *
856
- * // add items
857
- * // note that the data items can contain different properties and data formats
858
- * data.add([
859
- * {id: 1, text: 'item 1', date: new Date(2013, 6, 20), group: 1, first: true},
860
- * {id: 2, text: 'item 2', date: '2013-06-23', group: 2},
861
- * {id: 3, text: 'item 3', date: '2013-06-25', group: 2},
862
- * {id: 4, text: 'item 4'}
863
- * ]);
864
- *
865
- * // subscribe to any change in the DataSet
866
- * data.on('*', function (event, properties, senderId) {
867
- * console.log('event', event, properties);
868
- * });
869
- *
870
- * // update an existing item
871
- * data.update({id: 2, group: 1});
872
- *
873
- * // remove an item
874
- * data.remove(4);
875
- *
876
- * // get all ids
877
- * var ids = data.getIds();
878
- * console.log('ids', ids);
879
- *
880
- * // get a specific item
881
- * var item1 = data.get(1);
882
- * console.log('item1', item1);
883
- *
884
- * // retrieve a filtered subset of the data
885
- * var items = data.get({
886
- * filter: function (item) {
887
- * return item.group == 1;
888
- * }
889
- * });
890
- * console.log('filtered items', items);
891
- * ```
892
- *
893
- * @typeParam Item - Item type that may or may not have an id.
894
- * @typeParam IdProp - Name of the property that contains the id.
895
- */
896
- class DataSet extends DataSetPart {
897
- /**
898
- * Construct a new DataSet.
899
- *
900
- * @param data - Initial data or options.
901
- * @param options - Options (type error if data is also options).
902
- */
903
- constructor(data, options) {
904
- super();
905
- _options.set(this, void 0);
906
- _data.set(this, void 0);
907
- _idProp.set(this, void 0);
908
- _queue$1.set(this, null);
909
- // correctly read optional arguments
910
- if (data && !Array.isArray(data)) {
911
- options = data;
912
- data = [];
913
- }
914
- __classPrivateFieldSet(this, _options, options || {});
915
- __classPrivateFieldSet(this, _data, new Map()); // map with data indexed by id
916
- this.length = 0; // number of items in the DataSet
917
- __classPrivateFieldSet(// number of items in the DataSet
918
- this, _idProp, __classPrivateFieldGet(this, _options).fieldId || "id"); // name of the field containing id
919
- // add initial data when provided
920
- if (data && data.length) {
921
- this.add(data);
922
- }
923
- this.setOptions(options);
924
- }
925
- /** @inheritDoc */
926
- get idProp() {
927
- return __classPrivateFieldGet(this, _idProp);
928
- }
929
- /**
930
- * Set new options.
931
- *
932
- * @param options - The new options.
933
- */
934
- setOptions(options) {
935
- if (options && options.queue !== undefined) {
936
- if (options.queue === false) {
937
- // delete queue if loaded
938
- if (__classPrivateFieldGet(this, _queue$1)) {
939
- __classPrivateFieldGet(this, _queue$1).destroy();
940
- __classPrivateFieldSet(this, _queue$1, null);
941
- }
942
- }
943
- else {
944
- // create queue and update its options
945
- if (!__classPrivateFieldGet(this, _queue$1)) {
946
- __classPrivateFieldSet(this, _queue$1, Queue.extend(this, {
947
- replace: ["add", "update", "remove"],
948
- }));
949
- }
950
- if (options.queue && typeof options.queue === "object") {
951
- __classPrivateFieldGet(this, _queue$1).setOptions(options.queue);
952
- }
953
- }
954
- }
955
- }
956
- /**
957
- * Add a data item or an array with items.
958
- *
959
- * After the items are added to the DataSet, the DataSet will trigger an event `add`. When a `senderId` is provided, this id will be passed with the triggered event to all subscribers.
960
- *
961
- * ## Example
962
- *
963
- * ```javascript
964
- * // create a DataSet
965
- * const data = new vis.DataSet()
966
- *
967
- * // add items
968
- * const ids = data.add([
969
- * { id: 1, text: 'item 1' },
970
- * { id: 2, text: 'item 2' },
971
- * { text: 'item without an id' }
972
- * ])
973
- *
974
- * console.log(ids) // [1, 2, '<UUIDv4>']
975
- * ```
976
- *
977
- * @param data - Items to be added (ids will be generated if missing).
978
- * @param senderId - Sender id.
979
- *
980
- * @returns addedIds - Array with the ids (generated if not present) of the added items.
981
- *
982
- * @throws When an item with the same id as any of the added items already exists.
983
- */
984
- add(data, senderId) {
985
- const addedIds = [];
986
- let id;
987
- if (Array.isArray(data)) {
988
- // Array
989
- const idsToAdd = data.map((d) => d[__classPrivateFieldGet(this, _idProp)]);
990
- if (idsToAdd.some((id) => __classPrivateFieldGet(this, _data).has(id))) {
991
- throw new Error("A duplicate id was found in the parameter array.");
992
- }
993
- for (let i = 0, len = data.length; i < len; i++) {
994
- id = this._addItem(data[i]);
995
- addedIds.push(id);
996
- }
997
- }
998
- else if (data && typeof data === "object") {
999
- // Single item
1000
- id = this._addItem(data);
1001
- addedIds.push(id);
1002
- }
1003
- else {
1004
- throw new Error("Unknown dataType");
1005
- }
1006
- if (addedIds.length) {
1007
- this._trigger("add", { items: addedIds }, senderId);
1008
- }
1009
- return addedIds;
1010
- }
1011
- /**
1012
- * Update existing items. When an item does not exist, it will be created.
1013
- *
1014
- * @remarks
1015
- * The provided properties will be merged in the existing item. When an item does not exist, it will be created.
1016
- *
1017
- * After the items are updated, the DataSet will trigger an event `add` for the added items, and an event `update`. When a `senderId` is provided, this id will be passed with the triggered event to all subscribers.
1018
- *
1019
- * ## Example
1020
- *
1021
- * ```javascript
1022
- * // create a DataSet
1023
- * const data = new vis.DataSet([
1024
- * { id: 1, text: 'item 1' },
1025
- * { id: 2, text: 'item 2' },
1026
- * { id: 3, text: 'item 3' }
1027
- * ])
1028
- *
1029
- * // update items
1030
- * const ids = data.update([
1031
- * { id: 2, text: 'item 2 (updated)' },
1032
- * { id: 4, text: 'item 4 (new)' }
1033
- * ])
1034
- *
1035
- * console.log(ids) // [2, 4]
1036
- * ```
1037
- *
1038
- * ## Warning for TypeScript users
1039
- * This method may introduce partial items into the data set. Use add or updateOnly instead for better type safety.
1040
- *
1041
- * @param data - Items to be updated (if the id is already present) or added (if the id is missing).
1042
- * @param senderId - Sender id.
1043
- *
1044
- * @returns updatedIds - The ids of the added (these may be newly generated if there was no id in the item from the data) or updated items.
1045
- *
1046
- * @throws When the supplied data is neither an item nor an array of items.
1047
- */
1048
- update(data, senderId) {
1049
- const addedIds = [];
1050
- const updatedIds = [];
1051
- const oldData = [];
1052
- const updatedData = [];
1053
- const idProp = __classPrivateFieldGet(this, _idProp);
1054
- const addOrUpdate = (item) => {
1055
- const origId = item[idProp];
1056
- if (origId != null && __classPrivateFieldGet(this, _data).has(origId)) {
1057
- const fullItem = item; // it has an id, therefore it is a fullitem
1058
- const oldItem = Object.assign({}, __classPrivateFieldGet(this, _data).get(origId));
1059
- // update item
1060
- const id = this._updateItem(fullItem);
1061
- updatedIds.push(id);
1062
- updatedData.push(fullItem);
1063
- oldData.push(oldItem);
1064
- }
1065
- else {
1066
- // add new item
1067
- const id = this._addItem(item);
1068
- addedIds.push(id);
1069
- }
1070
- };
1071
- if (Array.isArray(data)) {
1072
- // Array
1073
- for (let i = 0, len = data.length; i < len; i++) {
1074
- if (data[i] && typeof data[i] === "object") {
1075
- addOrUpdate(data[i]);
1076
- }
1077
- else {
1078
- console.warn("Ignoring input item, which is not an object at index " + i);
1079
- }
1080
- }
1081
- }
1082
- else if (data && typeof data === "object") {
1083
- // Single item
1084
- addOrUpdate(data);
1085
- }
1086
- else {
1087
- throw new Error("Unknown dataType");
1088
- }
1089
- if (addedIds.length) {
1090
- this._trigger("add", { items: addedIds }, senderId);
1091
- }
1092
- if (updatedIds.length) {
1093
- const props = { items: updatedIds, oldData: oldData, data: updatedData };
1094
- // TODO: remove deprecated property 'data' some day
1095
- //Object.defineProperty(props, 'data', {
1096
- // 'get': (function() {
1097
- // console.warn('Property data is deprecated. Use DataSet.get(ids) to retrieve the new data, use the oldData property on this object to get the old data');
1098
- // return updatedData;
1099
- // }).bind(this)
1100
- //});
1101
- this._trigger("update", props, senderId);
1102
- }
1103
- return addedIds.concat(updatedIds);
1104
- }
1105
- /**
1106
- * Update existing items. When an item does not exist, an error will be thrown.
1107
- *
1108
- * @remarks
1109
- * The provided properties will be deeply merged into the existing item.
1110
- * When an item does not exist (id not present in the data set or absent), an error will be thrown and nothing will be changed.
1111
- *
1112
- * After the items are updated, the DataSet will trigger an event `update`.
1113
- * When a `senderId` is provided, this id will be passed with the triggered event to all subscribers.
1114
- *
1115
- * ## Example
1116
- *
1117
- * ```javascript
1118
- * // create a DataSet
1119
- * const data = new vis.DataSet([
1120
- * { id: 1, text: 'item 1' },
1121
- * { id: 2, text: 'item 2' },
1122
- * { id: 3, text: 'item 3' },
1123
- * ])
1124
- *
1125
- * // update items
1126
- * const ids = data.update([
1127
- * { id: 2, text: 'item 2 (updated)' }, // works
1128
- * // { id: 4, text: 'item 4 (new)' }, // would throw
1129
- * // { text: 'item 4 (new)' }, // would also throw
1130
- * ])
1131
- *
1132
- * console.log(ids) // [2]
1133
- * ```
1134
- *
1135
- * @param data - Updates (the id and optionally other props) to the items in this data set.
1136
- * @param senderId - Sender id.
1137
- *
1138
- * @returns updatedIds - The ids of the updated items.
1139
- *
1140
- * @throws When the supplied data is neither an item nor an array of items, when the ids are missing.
1141
- */
1142
- updateOnly(data, senderId) {
1143
- if (!Array.isArray(data)) {
1144
- data = [data];
1145
- }
1146
- const updateEventData = data
1147
- .map((update) => {
1148
- const oldData = __classPrivateFieldGet(this, _data).get(update[__classPrivateFieldGet(this, _idProp)]);
1149
- if (oldData == null) {
1150
- throw new Error("Updating non-existent items is not allowed.");
1151
- }
1152
- return { oldData, update };
1153
- })
1154
- .map(({ oldData, update }) => {
1155
- const id = oldData[__classPrivateFieldGet(this, _idProp)];
1156
- const updatedData = esnext.pureDeepObjectAssign(oldData, update);
1157
- __classPrivateFieldGet(this, _data).set(id, updatedData);
1158
- return {
1159
- id,
1160
- oldData: oldData,
1161
- updatedData,
1162
- };
1163
- });
1164
- if (updateEventData.length) {
1165
- const props = {
1166
- items: updateEventData.map((value) => value.id),
1167
- oldData: updateEventData.map((value) => value.oldData),
1168
- data: updateEventData.map((value) => value.updatedData),
1169
- };
1170
- // TODO: remove deprecated property 'data' some day
1171
- //Object.defineProperty(props, 'data', {
1172
- // 'get': (function() {
1173
- // console.warn('Property data is deprecated. Use DataSet.get(ids) to retrieve the new data, use the oldData property on this object to get the old data');
1174
- // return updatedData;
1175
- // }).bind(this)
1176
- //});
1177
- this._trigger("update", props, senderId);
1178
- return props.items;
1179
- }
1180
- else {
1181
- return [];
1182
- }
1183
- }
1184
- /** @inheritDoc */
1185
- get(first, second) {
1186
- // @TODO: Woudn't it be better to split this into multiple methods?
1187
- // parse the arguments
1188
- let id = undefined;
1189
- let ids = undefined;
1190
- let options = undefined;
1191
- if (isId(first)) {
1192
- // get(id [, options])
1193
- id = first;
1194
- options = second;
1195
- }
1196
- else if (Array.isArray(first)) {
1197
- // get(ids [, options])
1198
- ids = first;
1199
- options = second;
1200
- }
1201
- else {
1202
- // get([, options])
1203
- options = first;
1204
- }
1205
- // determine the return type
1206
- const returnType = options && options.returnType === "Object" ? "Object" : "Array";
1207
- // @TODO: WTF is this? Or am I missing something?
1208
- // var returnType
1209
- // if (options && options.returnType) {
1210
- // var allowedValues = ['Array', 'Object']
1211
- // returnType =
1212
- // allowedValues.indexOf(options.returnType) == -1
1213
- // ? 'Array'
1214
- // : options.returnType
1215
- // } else {
1216
- // returnType = 'Array'
1217
- // }
1218
- // build options
1219
- const filter = options && options.filter;
1220
- const items = [];
1221
- let item = undefined;
1222
- let itemIds = undefined;
1223
- let itemId = undefined;
1224
- // convert items
1225
- if (id != null) {
1226
- // return a single item
1227
- item = __classPrivateFieldGet(this, _data).get(id);
1228
- if (item && filter && !filter(item)) {
1229
- item = undefined;
1230
- }
1231
- }
1232
- else if (ids != null) {
1233
- // return a subset of items
1234
- for (let i = 0, len = ids.length; i < len; i++) {
1235
- item = __classPrivateFieldGet(this, _data).get(ids[i]);
1236
- if (item != null && (!filter || filter(item))) {
1237
- items.push(item);
1238
- }
1239
- }
1240
- }
1241
- else {
1242
- // return all items
1243
- itemIds = [...__classPrivateFieldGet(this, _data).keys()];
1244
- for (let i = 0, len = itemIds.length; i < len; i++) {
1245
- itemId = itemIds[i];
1246
- item = __classPrivateFieldGet(this, _data).get(itemId);
1247
- if (item != null && (!filter || filter(item))) {
1248
- items.push(item);
1249
- }
1250
- }
1251
- }
1252
- // order the results
1253
- if (options && options.order && id == undefined) {
1254
- this._sort(items, options.order);
1255
- }
1256
- // filter fields of the items
1257
- if (options && options.fields) {
1258
- const fields = options.fields;
1259
- if (id != undefined && item != null) {
1260
- item = this._filterFields(item, fields);
1261
- }
1262
- else {
1263
- for (let i = 0, len = items.length; i < len; i++) {
1264
- items[i] = this._filterFields(items[i], fields);
1265
- }
1266
- }
1267
- }
1268
- // return the results
1269
- if (returnType == "Object") {
1270
- const result = {};
1271
- for (let i = 0, len = items.length; i < len; i++) {
1272
- const resultant = items[i];
1273
- // @TODO: Shoudn't this be this._fieldId?
1274
- // result[resultant.id] = resultant
1275
- const id = resultant[__classPrivateFieldGet(this, _idProp)];
1276
- result[id] = resultant;
1277
- }
1278
- return result;
1279
- }
1280
- else {
1281
- if (id != null) {
1282
- // a single item
1283
- return item !== null && item !== void 0 ? item : null;
1284
- }
1285
- else {
1286
- // just return our array
1287
- return items;
1288
- }
1289
- }
1290
- }
1291
- /** @inheritDoc */
1292
- getIds(options) {
1293
- const data = __classPrivateFieldGet(this, _data);
1294
- const filter = options && options.filter;
1295
- const order = options && options.order;
1296
- const itemIds = [...data.keys()];
1297
- const ids = [];
1298
- if (filter) {
1299
- // get filtered items
1300
- if (order) {
1301
- // create ordered list
1302
- const items = [];
1303
- for (let i = 0, len = itemIds.length; i < len; i++) {
1304
- const id = itemIds[i];
1305
- const item = __classPrivateFieldGet(this, _data).get(id);
1306
- if (item != null && filter(item)) {
1307
- items.push(item);
1308
- }
1309
- }
1310
- this._sort(items, order);
1311
- for (let i = 0, len = items.length; i < len; i++) {
1312
- ids.push(items[i][__classPrivateFieldGet(this, _idProp)]);
1313
- }
1314
- }
1315
- else {
1316
- // create unordered list
1317
- for (let i = 0, len = itemIds.length; i < len; i++) {
1318
- const id = itemIds[i];
1319
- const item = __classPrivateFieldGet(this, _data).get(id);
1320
- if (item != null && filter(item)) {
1321
- ids.push(item[__classPrivateFieldGet(this, _idProp)]);
1322
- }
1323
- }
1324
- }
1325
- }
1326
- else {
1327
- // get all items
1328
- if (order) {
1329
- // create an ordered list
1330
- const items = [];
1331
- for (let i = 0, len = itemIds.length; i < len; i++) {
1332
- const id = itemIds[i];
1333
- items.push(data.get(id));
1334
- }
1335
- this._sort(items, order);
1336
- for (let i = 0, len = items.length; i < len; i++) {
1337
- ids.push(items[i][__classPrivateFieldGet(this, _idProp)]);
1338
- }
1339
- }
1340
- else {
1341
- // create unordered list
1342
- for (let i = 0, len = itemIds.length; i < len; i++) {
1343
- const id = itemIds[i];
1344
- const item = data.get(id);
1345
- if (item != null) {
1346
- ids.push(item[__classPrivateFieldGet(this, _idProp)]);
1347
- }
1348
- }
1349
- }
1350
- }
1351
- return ids;
1352
- }
1353
- /** @inheritDoc */
1354
- getDataSet() {
1355
- return this;
1356
- }
1357
- /** @inheritDoc */
1358
- forEach(callback, options) {
1359
- const filter = options && options.filter;
1360
- const data = __classPrivateFieldGet(this, _data);
1361
- const itemIds = [...data.keys()];
1362
- if (options && options.order) {
1363
- // execute forEach on ordered list
1364
- const items = this.get(options);
1365
- for (let i = 0, len = items.length; i < len; i++) {
1366
- const item = items[i];
1367
- const id = item[__classPrivateFieldGet(this, _idProp)];
1368
- callback(item, id);
1369
- }
1370
- }
1371
- else {
1372
- // unordered
1373
- for (let i = 0, len = itemIds.length; i < len; i++) {
1374
- const id = itemIds[i];
1375
- const item = __classPrivateFieldGet(this, _data).get(id);
1376
- if (item != null && (!filter || filter(item))) {
1377
- callback(item, id);
1378
- }
1379
- }
1380
- }
1381
- }
1382
- /** @inheritDoc */
1383
- map(callback, options) {
1384
- const filter = options && options.filter;
1385
- const mappedItems = [];
1386
- const data = __classPrivateFieldGet(this, _data);
1387
- const itemIds = [...data.keys()];
1388
- // convert and filter items
1389
- for (let i = 0, len = itemIds.length; i < len; i++) {
1390
- const id = itemIds[i];
1391
- const item = __classPrivateFieldGet(this, _data).get(id);
1392
- if (item != null && (!filter || filter(item))) {
1393
- mappedItems.push(callback(item, id));
1394
- }
1395
- }
1396
- // order items
1397
- if (options && options.order) {
1398
- this._sort(mappedItems, options.order);
1399
- }
1400
- return mappedItems;
1401
- }
1402
- /**
1403
- * Filter the fields of an item.
1404
- *
1405
- * @param item - The item whose fields should be filtered.
1406
- * @param fields - The names of the fields that will be kept.
1407
- *
1408
- * @typeParam K - Field name type.
1409
- *
1410
- * @returns The item without any additional fields.
1411
- */
1412
- _filterFields(item, fields) {
1413
- if (!item) {
1414
- // item is null
1415
- return item;
1416
- }
1417
- return (Array.isArray(fields)
1418
- ? // Use the supplied array
1419
- fields
1420
- : // Use the keys of the supplied object
1421
- Object.keys(fields)).reduce((filteredItem, field) => {
1422
- filteredItem[field] = item[field];
1423
- return filteredItem;
1424
- }, {});
1425
- }
1426
- /**
1427
- * Sort the provided array with items.
1428
- *
1429
- * @param items - Items to be sorted in place.
1430
- * @param order - A field name or custom sort function.
1431
- *
1432
- * @typeParam T - The type of the items in the items array.
1433
- */
1434
- _sort(items, order) {
1435
- if (typeof order === "string") {
1436
- // order by provided field name
1437
- const name = order; // field name
1438
- items.sort((a, b) => {
1439
- // @TODO: How to treat missing properties?
1440
- const av = a[name];
1441
- const bv = b[name];
1442
- return av > bv ? 1 : av < bv ? -1 : 0;
1443
- });
1444
- }
1445
- else if (typeof order === "function") {
1446
- // order by sort function
1447
- items.sort(order);
1448
- }
1449
- else {
1450
- // TODO: extend order by an Object {field:string, direction:string}
1451
- // where direction can be 'asc' or 'desc'
1452
- throw new TypeError("Order must be a function or a string");
1453
- }
1454
- }
1455
- /**
1456
- * Remove an item or multiple items by “reference” (only the id is used) or by id.
1457
- *
1458
- * The method ignores removal of non-existing items, and returns an array containing the ids of the items which are actually removed from the DataSet.
1459
- *
1460
- * After the items are removed, the DataSet will trigger an event `remove` for the removed items. When a `senderId` is provided, this id will be passed with the triggered event to all subscribers.
1461
- *
1462
- * ## Example
1463
- * ```javascript
1464
- * // create a DataSet
1465
- * const data = new vis.DataSet([
1466
- * { id: 1, text: 'item 1' },
1467
- * { id: 2, text: 'item 2' },
1468
- * { id: 3, text: 'item 3' }
1469
- * ])
1470
- *
1471
- * // remove items
1472
- * const ids = data.remove([2, { id: 3 }, 4])
1473
- *
1474
- * console.log(ids) // [2, 3]
1475
- * ```
1476
- *
1477
- * @param id - One or more items or ids of items to be removed.
1478
- * @param senderId - Sender id.
1479
- *
1480
- * @returns The ids of the removed items.
1481
- */
1482
- remove(id, senderId) {
1483
- const removedIds = [];
1484
- const removedItems = [];
1485
- // force everything to be an array for simplicity
1486
- const ids = Array.isArray(id) ? id : [id];
1487
- for (let i = 0, len = ids.length; i < len; i++) {
1488
- const item = this._remove(ids[i]);
1489
- if (item) {
1490
- const itemId = item[__classPrivateFieldGet(this, _idProp)];
1491
- if (itemId != null) {
1492
- removedIds.push(itemId);
1493
- removedItems.push(item);
1494
- }
1495
- }
1496
- }
1497
- if (removedIds.length) {
1498
- this._trigger("remove", { items: removedIds, oldData: removedItems }, senderId);
1499
- }
1500
- return removedIds;
1501
- }
1502
- /**
1503
- * Remove an item by its id or reference.
1504
- *
1505
- * @param id - Id of an item or the item itself.
1506
- *
1507
- * @returns The removed item if removed, null otherwise.
1508
- */
1509
- _remove(id) {
1510
- // @TODO: It origianlly returned the item although the docs say id.
1511
- // The code expects the item, so probably an error in the docs.
1512
- let ident;
1513
- // confirm the id to use based on the args type
1514
- if (isId(id)) {
1515
- ident = id;
1516
- }
1517
- else if (id && typeof id === "object") {
1518
- ident = id[__classPrivateFieldGet(this, _idProp)]; // look for the identifier field using ._idProp
1519
- }
1520
- // do the removing if the item is found
1521
- if (ident != null && __classPrivateFieldGet(this, _data).has(ident)) {
1522
- const item = __classPrivateFieldGet(this, _data).get(ident) || null;
1523
- __classPrivateFieldGet(this, _data).delete(ident);
1524
- --this.length;
1525
- return item;
1526
- }
1527
- return null;
1528
- }
1529
- /**
1530
- * Clear the entire data set.
1531
- *
1532
- * After the items are removed, the [[DataSet]] will trigger an event `remove` for all removed items. When a `senderId` is provided, this id will be passed with the triggered event to all subscribers.
1533
- *
1534
- * @param senderId - Sender id.
1535
- *
1536
- * @returns removedIds - The ids of all removed items.
1537
- */
1538
- clear(senderId) {
1539
- const ids = [...__classPrivateFieldGet(this, _data).keys()];
1540
- const items = [];
1541
- for (let i = 0, len = ids.length; i < len; i++) {
1542
- items.push(__classPrivateFieldGet(this, _data).get(ids[i]));
1543
- }
1544
- __classPrivateFieldGet(this, _data).clear();
1545
- this.length = 0;
1546
- this._trigger("remove", { items: ids, oldData: items }, senderId);
1547
- return ids;
1548
- }
1549
- /**
1550
- * Find the item with maximum value of a specified field.
1551
- *
1552
- * @param field - Name of the property that should be searched for max value.
1553
- *
1554
- * @returns Item containing max value, or null if no items.
1555
- */
1556
- max(field) {
1557
- let max = null;
1558
- let maxField = null;
1559
- for (const item of __classPrivateFieldGet(this, _data).values()) {
1560
- const itemField = item[field];
1561
- if (typeof itemField === "number" &&
1562
- (maxField == null || itemField > maxField)) {
1563
- max = item;
1564
- maxField = itemField;
1565
- }
1566
- }
1567
- return max || null;
1568
- }
1569
- /**
1570
- * Find the item with minimum value of a specified field.
1571
- *
1572
- * @param field - Name of the property that should be searched for min value.
1573
- *
1574
- * @returns Item containing min value, or null if no items.
1575
- */
1576
- min(field) {
1577
- let min = null;
1578
- let minField = null;
1579
- for (const item of __classPrivateFieldGet(this, _data).values()) {
1580
- const itemField = item[field];
1581
- if (typeof itemField === "number" &&
1582
- (minField == null || itemField < minField)) {
1583
- min = item;
1584
- minField = itemField;
1585
- }
1586
- }
1587
- return min || null;
1588
- }
1589
- /**
1590
- * Find all distinct values of a specified field
1591
- *
1592
- * @param prop - The property name whose distinct values should be returned.
1593
- *
1594
- * @returns Unordered array containing all distinct values. Items without specified property are ignored.
1595
- */
1596
- distinct(prop) {
1597
- const data = __classPrivateFieldGet(this, _data);
1598
- const itemIds = [...data.keys()];
1599
- const values = [];
1600
- let count = 0;
1601
- for (let i = 0, len = itemIds.length; i < len; i++) {
1602
- const id = itemIds[i];
1603
- const item = data.get(id);
1604
- const value = item[prop];
1605
- let exists = false;
1606
- for (let j = 0; j < count; j++) {
1607
- if (values[j] == value) {
1608
- exists = true;
1609
- break;
1610
- }
1611
- }
1612
- if (!exists && value !== undefined) {
1613
- values[count] = value;
1614
- count++;
1615
- }
1616
- }
1617
- return values;
1618
- }
1619
- /**
1620
- * Add a single item. Will fail when an item with the same id already exists.
1621
- *
1622
- * @param item - A new item to be added.
1623
- *
1624
- * @returns Added item's id. An id is generated when it is not present in the item.
1625
- */
1626
- _addItem(item) {
1627
- const fullItem = ensureFullItem(item, __classPrivateFieldGet(this, _idProp));
1628
- const id = fullItem[__classPrivateFieldGet(this, _idProp)];
1629
- // check whether this id is already taken
1630
- if (__classPrivateFieldGet(this, _data).has(id)) {
1631
- // item already exists
1632
- throw new Error("Cannot add item: item with id " + id + " already exists");
1633
- }
1634
- __classPrivateFieldGet(this, _data).set(id, fullItem);
1635
- ++this.length;
1636
- return id;
1637
- }
1638
- /**
1639
- * Update a single item: merge with existing item.
1640
- * Will fail when the item has no id, or when there does not exist an item with the same id.
1641
- *
1642
- * @param update - The new item
1643
- *
1644
- * @returns The id of the updated item.
1645
- */
1646
- _updateItem(update) {
1647
- const id = update[__classPrivateFieldGet(this, _idProp)];
1648
- if (id == null) {
1649
- throw new Error("Cannot update item: item has no id (item: " +
1650
- JSON.stringify(update) +
1651
- ")");
1652
- }
1653
- const item = __classPrivateFieldGet(this, _data).get(id);
1654
- if (!item) {
1655
- // item doesn't exist
1656
- throw new Error("Cannot update item: no item with id " + id + " found");
1657
- }
1658
- __classPrivateFieldGet(this, _data).set(id, { ...item, ...update });
1659
- return id;
1660
- }
1661
- /** @inheritDoc */
1662
- stream(ids) {
1663
- if (ids) {
1664
- const data = __classPrivateFieldGet(this, _data);
1665
- return new DataStream({
1666
- *[Symbol.iterator]() {
1667
- for (const id of ids) {
1668
- const item = data.get(id);
1669
- if (item != null) {
1670
- yield [id, item];
1671
- }
1672
- }
1673
- },
1674
- });
1675
- }
1676
- else {
1677
- return new DataStream({
1678
- [Symbol.iterator]: __classPrivateFieldGet(this, _data).entries.bind(__classPrivateFieldGet(this, _data)),
1679
- });
1680
- }
1681
- }
1682
- }
1683
- _options = new WeakMap(), _data = new WeakMap(), _idProp = new WeakMap(), _queue$1 = new WeakMap();
1590
+ /**
1591
+ * DataView
1592
+ *
1593
+ * A DataView offers a filtered and/or formatted view on a DataSet. One can subscribe to changes in a DataView, and easily get filtered or formatted data without having to specify filters and field types all the time.
1594
+ *
1595
+ * ## Example
1596
+ * ```javascript
1597
+ * // create a DataSet
1598
+ * var data = new vis.DataSet();
1599
+ * data.add([
1600
+ * {id: 1, text: 'item 1', date: new Date(2013, 6, 20), group: 1, first: true},
1601
+ * {id: 2, text: 'item 2', date: '2013-06-23', group: 2},
1602
+ * {id: 3, text: 'item 3', date: '2013-06-25', group: 2},
1603
+ * {id: 4, text: 'item 4'}
1604
+ * ]);
1605
+ *
1606
+ * // create a DataView
1607
+ * // the view will only contain items having a property group with value 1,
1608
+ * // and will only output fields id, text, and date.
1609
+ * var view = new vis.DataView(data, {
1610
+ * filter: function (item) {
1611
+ * return (item.group == 1);
1612
+ * },
1613
+ * fields: ['id', 'text', 'date']
1614
+ * });
1615
+ *
1616
+ * // subscribe to any change in the DataView
1617
+ * view.on('*', function (event, properties, senderId) {
1618
+ * console.log('event', event, properties);
1619
+ * });
1620
+ *
1621
+ * // update an item in the data set
1622
+ * data.update({id: 2, group: 1});
1623
+ *
1624
+ * // get all ids in the view
1625
+ * var ids = view.getIds();
1626
+ * console.log('ids', ids); // will output [1, 2]
1627
+ *
1628
+ * // get all items in the view
1629
+ * var items = view.get();
1630
+ * ```
1631
+ *
1632
+ * @typeParam Item - Item type that may or may not have an id.
1633
+ * @typeParam IdProp - Name of the property that contains the id.
1634
+ */
1635
+ class DataView extends DataSetPart {
1636
+ /**
1637
+ * Create a DataView.
1638
+ *
1639
+ * @param data - The instance containing data (directly or indirectly).
1640
+ * @param options - Options to configure this data view.
1641
+ */
1642
+ constructor(data, options) {
1643
+ super();
1644
+ /** @inheritDoc */
1645
+ this.length = 0;
1646
+ this._ids = new Set(); // ids of the items currently in memory (just contains a boolean true)
1647
+ this._options = options || {};
1648
+ this._listener = this._onEvent.bind(this);
1649
+ this.setData(data);
1650
+ }
1651
+ /** @inheritDoc */
1652
+ get idProp() {
1653
+ return this.getDataSet().idProp;
1654
+ }
1655
+ // TODO: implement a function .config() to dynamically update things like configured filter
1656
+ // and trigger changes accordingly
1657
+ /**
1658
+ * Set a data source for the view.
1659
+ *
1660
+ * @param data - The instance containing data (directly or indirectly).
1661
+ * @remarks
1662
+ * Note that when the data view is bound to a data set it won't be garbage
1663
+ * collected unless the data set is too. Use `dataView.setData(null)` or
1664
+ * `dataView.dispose()` to enable garbage collection before you lose the last
1665
+ * reference.
1666
+ */
1667
+ setData(data) {
1668
+ if (this._data) {
1669
+ // unsubscribe from current dataset
1670
+ if (this._data.off) {
1671
+ this._data.off("*", this._listener);
1672
+ }
1673
+ // trigger a remove of all items in memory
1674
+ const ids = this._data.getIds({ filter: this._options.filter });
1675
+ const items = this._data.get(ids);
1676
+ this._ids.clear();
1677
+ this.length = 0;
1678
+ this._trigger("remove", { items: ids, oldData: items });
1679
+ }
1680
+ if (data != null) {
1681
+ this._data = data;
1682
+ // trigger an add of all added items
1683
+ const ids = this._data.getIds({ filter: this._options.filter });
1684
+ for (let i = 0, len = ids.length; i < len; i++) {
1685
+ const id = ids[i];
1686
+ this._ids.add(id);
1687
+ }
1688
+ this.length = ids.length;
1689
+ this._trigger("add", { items: ids });
1690
+ }
1691
+ else {
1692
+ this._data = new DataSet();
1693
+ }
1694
+ // subscribe to new dataset
1695
+ if (this._data.on) {
1696
+ this._data.on("*", this._listener);
1697
+ }
1698
+ }
1699
+ /**
1700
+ * Refresh the DataView.
1701
+ * Useful when the DataView has a filter function containing a variable parameter.
1702
+ */
1703
+ refresh() {
1704
+ const ids = this._data.getIds({
1705
+ filter: this._options.filter,
1706
+ });
1707
+ const oldIds = [...this._ids];
1708
+ const newIds = {};
1709
+ const addedIds = [];
1710
+ const removedIds = [];
1711
+ const removedItems = [];
1712
+ // check for additions
1713
+ for (let i = 0, len = ids.length; i < len; i++) {
1714
+ const id = ids[i];
1715
+ newIds[id] = true;
1716
+ if (!this._ids.has(id)) {
1717
+ addedIds.push(id);
1718
+ this._ids.add(id);
1719
+ }
1720
+ }
1721
+ // check for removals
1722
+ for (let i = 0, len = oldIds.length; i < len; i++) {
1723
+ const id = oldIds[i];
1724
+ const item = this._data.get(id);
1725
+ if (item == null) {
1726
+ // @TODO: Investigate.
1727
+ // Doesn't happen during tests or examples.
1728
+ // Is it really impossible or could it eventually happen?
1729
+ // How to handle it if it does? The types guarantee non-nullable items.
1730
+ console.error("If you see this, report it please.");
1731
+ }
1732
+ else if (!newIds[id]) {
1733
+ removedIds.push(id);
1734
+ removedItems.push(item);
1735
+ this._ids.delete(id);
1736
+ }
1737
+ }
1738
+ this.length += addedIds.length - removedIds.length;
1739
+ // trigger events
1740
+ if (addedIds.length) {
1741
+ this._trigger("add", { items: addedIds });
1742
+ }
1743
+ if (removedIds.length) {
1744
+ this._trigger("remove", { items: removedIds, oldData: removedItems });
1745
+ }
1746
+ }
1747
+ /** @inheritDoc */
1748
+ get(first, second) {
1749
+ if (this._data == null) {
1750
+ return null;
1751
+ }
1752
+ // parse the arguments
1753
+ let ids = null;
1754
+ let options;
1755
+ if (isId(first) || Array.isArray(first)) {
1756
+ ids = first;
1757
+ options = second;
1758
+ }
1759
+ else {
1760
+ options = first;
1761
+ }
1762
+ // extend the options with the default options and provided options
1763
+ const viewOptions = Object.assign({}, this._options, options);
1764
+ // create a combined filter method when needed
1765
+ const thisFilter = this._options.filter;
1766
+ const optionsFilter = options && options.filter;
1767
+ if (thisFilter && optionsFilter) {
1768
+ viewOptions.filter = (item) => {
1769
+ return thisFilter(item) && optionsFilter(item);
1770
+ };
1771
+ }
1772
+ if (ids == null) {
1773
+ return this._data.get(viewOptions);
1774
+ }
1775
+ else {
1776
+ return this._data.get(ids, viewOptions);
1777
+ }
1778
+ }
1779
+ /** @inheritDoc */
1780
+ getIds(options) {
1781
+ if (this._data.length) {
1782
+ const defaultFilter = this._options.filter;
1783
+ const optionsFilter = options != null ? options.filter : null;
1784
+ let filter;
1785
+ if (optionsFilter) {
1786
+ if (defaultFilter) {
1787
+ filter = (item) => {
1788
+ return defaultFilter(item) && optionsFilter(item);
1789
+ };
1790
+ }
1791
+ else {
1792
+ filter = optionsFilter;
1793
+ }
1794
+ }
1795
+ else {
1796
+ filter = defaultFilter;
1797
+ }
1798
+ return this._data.getIds({
1799
+ filter: filter,
1800
+ order: options && options.order,
1801
+ });
1802
+ }
1803
+ else {
1804
+ return [];
1805
+ }
1806
+ }
1807
+ /** @inheritDoc */
1808
+ forEach(callback, options) {
1809
+ if (this._data) {
1810
+ const defaultFilter = this._options.filter;
1811
+ const optionsFilter = options && options.filter;
1812
+ let filter;
1813
+ if (optionsFilter) {
1814
+ if (defaultFilter) {
1815
+ filter = function (item) {
1816
+ return defaultFilter(item) && optionsFilter(item);
1817
+ };
1818
+ }
1819
+ else {
1820
+ filter = optionsFilter;
1821
+ }
1822
+ }
1823
+ else {
1824
+ filter = defaultFilter;
1825
+ }
1826
+ this._data.forEach(callback, {
1827
+ filter: filter,
1828
+ order: options && options.order,
1829
+ });
1830
+ }
1831
+ }
1832
+ /** @inheritDoc */
1833
+ map(callback, options) {
1834
+ if (this._data) {
1835
+ const defaultFilter = this._options.filter;
1836
+ const optionsFilter = options && options.filter;
1837
+ let filter;
1838
+ if (optionsFilter) {
1839
+ if (defaultFilter) {
1840
+ filter = (item) => {
1841
+ return defaultFilter(item) && optionsFilter(item);
1842
+ };
1843
+ }
1844
+ else {
1845
+ filter = optionsFilter;
1846
+ }
1847
+ }
1848
+ else {
1849
+ filter = defaultFilter;
1850
+ }
1851
+ return this._data.map(callback, {
1852
+ filter: filter,
1853
+ order: options && options.order,
1854
+ });
1855
+ }
1856
+ else {
1857
+ return [];
1858
+ }
1859
+ }
1860
+ /** @inheritDoc */
1861
+ getDataSet() {
1862
+ return this._data.getDataSet();
1863
+ }
1864
+ /** @inheritDoc */
1865
+ stream(ids) {
1866
+ return this._data.stream(ids || {
1867
+ [Symbol.iterator]: this._ids.keys.bind(this._ids),
1868
+ });
1869
+ }
1870
+ /**
1871
+ * Render the instance unusable prior to garbage collection.
1872
+ *
1873
+ * @remarks
1874
+ * The intention of this method is to help discover scenarios where the data
1875
+ * view is being used when the programmer thinks it has been garbage collected
1876
+ * already. It's stricter version of `dataView.setData(null)`.
1877
+ */
1878
+ dispose() {
1879
+ if (this._data?.off) {
1880
+ this._data.off("*", this._listener);
1881
+ }
1882
+ const message = "This data view has already been disposed of.";
1883
+ const replacement = {
1884
+ get: () => {
1885
+ throw new Error(message);
1886
+ },
1887
+ set: () => {
1888
+ throw new Error(message);
1889
+ },
1890
+ configurable: false,
1891
+ };
1892
+ for (const key of Reflect.ownKeys(DataView.prototype)) {
1893
+ Object.defineProperty(this, key, replacement);
1894
+ }
1895
+ }
1896
+ /**
1897
+ * Event listener. Will propagate all events from the connected data set to the subscribers of the DataView, but will filter the items and only trigger when there are changes in the filtered data set.
1898
+ *
1899
+ * @param event - The name of the event.
1900
+ * @param params - Parameters of the event.
1901
+ * @param senderId - Id supplied by the sender.
1902
+ */
1903
+ _onEvent(event, params, senderId) {
1904
+ if (!params || !params.items || !this._data) {
1905
+ return;
1906
+ }
1907
+ const ids = params.items;
1908
+ const addedIds = [];
1909
+ const updatedIds = [];
1910
+ const removedIds = [];
1911
+ const oldItems = [];
1912
+ const updatedItems = [];
1913
+ const removedItems = [];
1914
+ switch (event) {
1915
+ case "add":
1916
+ // filter the ids of the added items
1917
+ for (let i = 0, len = ids.length; i < len; i++) {
1918
+ const id = ids[i];
1919
+ const item = this.get(id);
1920
+ if (item) {
1921
+ this._ids.add(id);
1922
+ addedIds.push(id);
1923
+ }
1924
+ }
1925
+ break;
1926
+ case "update":
1927
+ // determine the event from the views viewpoint: an updated
1928
+ // item can be added, updated, or removed from this view.
1929
+ for (let i = 0, len = ids.length; i < len; i++) {
1930
+ const id = ids[i];
1931
+ const item = this.get(id);
1932
+ if (item) {
1933
+ if (this._ids.has(id)) {
1934
+ updatedIds.push(id);
1935
+ updatedItems.push(params.data[i]);
1936
+ oldItems.push(params.oldData[i]);
1937
+ }
1938
+ else {
1939
+ this._ids.add(id);
1940
+ addedIds.push(id);
1941
+ }
1942
+ }
1943
+ else {
1944
+ if (this._ids.has(id)) {
1945
+ this._ids.delete(id);
1946
+ removedIds.push(id);
1947
+ removedItems.push(params.oldData[i]);
1948
+ }
1949
+ }
1950
+ }
1951
+ break;
1952
+ case "remove":
1953
+ // filter the ids of the removed items
1954
+ for (let i = 0, len = ids.length; i < len; i++) {
1955
+ const id = ids[i];
1956
+ if (this._ids.has(id)) {
1957
+ this._ids.delete(id);
1958
+ removedIds.push(id);
1959
+ removedItems.push(params.oldData[i]);
1960
+ }
1961
+ }
1962
+ break;
1963
+ }
1964
+ this.length += addedIds.length - removedIds.length;
1965
+ if (addedIds.length) {
1966
+ this._trigger("add", { items: addedIds }, senderId);
1967
+ }
1968
+ if (updatedIds.length) {
1969
+ this._trigger("update", { items: updatedIds, oldData: oldItems, data: updatedItems }, senderId);
1970
+ }
1971
+ if (removedIds.length) {
1972
+ this._trigger("remove", { items: removedIds, oldData: removedItems }, senderId);
1973
+ }
1974
+ }
1975
+ }
1684
1976
 
1685
- var _listener, _data$1, _ids, _options$1;
1686
- /**
1687
- * DataView
1688
- *
1689
- * A DataView offers a filtered and/or formatted view on a DataSet. One can subscribe to changes in a DataView, and easily get filtered or formatted data without having to specify filters and field types all the time.
1690
- *
1691
- * ## Example
1692
- * ```javascript
1693
- * // create a DataSet
1694
- * var data = new vis.DataSet();
1695
- * data.add([
1696
- * {id: 1, text: 'item 1', date: new Date(2013, 6, 20), group: 1, first: true},
1697
- * {id: 2, text: 'item 2', date: '2013-06-23', group: 2},
1698
- * {id: 3, text: 'item 3', date: '2013-06-25', group: 2},
1699
- * {id: 4, text: 'item 4'}
1700
- * ]);
1701
- *
1702
- * // create a DataView
1703
- * // the view will only contain items having a property group with value 1,
1704
- * // and will only output fields id, text, and date.
1705
- * var view = new vis.DataView(data, {
1706
- * filter: function (item) {
1707
- * return (item.group == 1);
1708
- * },
1709
- * fields: ['id', 'text', 'date']
1710
- * });
1711
- *
1712
- * // subscribe to any change in the DataView
1713
- * view.on('*', function (event, properties, senderId) {
1714
- * console.log('event', event, properties);
1715
- * });
1716
- *
1717
- * // update an item in the data set
1718
- * data.update({id: 2, group: 1});
1719
- *
1720
- * // get all ids in the view
1721
- * var ids = view.getIds();
1722
- * console.log('ids', ids); // will output [1, 2]
1723
- *
1724
- * // get all items in the view
1725
- * var items = view.get();
1726
- * ```
1727
- *
1728
- * @typeParam Item - Item type that may or may not have an id.
1729
- * @typeParam IdProp - Name of the property that contains the id.
1730
- */
1731
- class DataView extends DataSetPart {
1732
- /**
1733
- * Create a DataView.
1734
- *
1735
- * @param data - The instance containing data (directly or indirectly).
1736
- * @param options - Options to configure this data view.
1737
- */
1738
- constructor(data, options) {
1739
- super();
1740
- /** @inheritDoc */
1741
- this.length = 0;
1742
- _listener.set(this, void 0);
1743
- _data$1.set(this, void 0); // constructor → setData
1744
- _ids.set(this, new Set()); // ids of the items currently in memory (just contains a boolean true)
1745
- _options$1.set(this, void 0);
1746
- __classPrivateFieldSet(this, _options$1, options || {});
1747
- __classPrivateFieldSet(this, _listener, this._onEvent.bind(this));
1748
- this.setData(data);
1749
- }
1750
- /** @inheritDoc */
1751
- get idProp() {
1752
- return this.getDataSet().idProp;
1753
- }
1754
- // TODO: implement a function .config() to dynamically update things like configured filter
1755
- // and trigger changes accordingly
1756
- /**
1757
- * Set a data source for the view.
1758
- *
1759
- * @param data - The instance containing data (directly or indirectly).
1760
- *
1761
- * @remarks
1762
- * Note that when the data view is bound to a data set it won't be garbage
1763
- * collected unless the data set is too. Use `dataView.setData(null)` or
1764
- * `dataView.dispose()` to enable garbage collection before you lose the last
1765
- * reference.
1766
- */
1767
- setData(data) {
1768
- if (__classPrivateFieldGet(this, _data$1)) {
1769
- // unsubscribe from current dataset
1770
- if (__classPrivateFieldGet(this, _data$1).off) {
1771
- __classPrivateFieldGet(this, _data$1).off("*", __classPrivateFieldGet(this, _listener));
1772
- }
1773
- // trigger a remove of all items in memory
1774
- const ids = __classPrivateFieldGet(this, _data$1).getIds({ filter: __classPrivateFieldGet(this, _options$1).filter });
1775
- const items = __classPrivateFieldGet(this, _data$1).get(ids);
1776
- __classPrivateFieldGet(this, _ids).clear();
1777
- this.length = 0;
1778
- this._trigger("remove", { items: ids, oldData: items });
1779
- }
1780
- if (data != null) {
1781
- __classPrivateFieldSet(this, _data$1, data);
1782
- // trigger an add of all added items
1783
- const ids = __classPrivateFieldGet(this, _data$1).getIds({ filter: __classPrivateFieldGet(this, _options$1).filter });
1784
- for (let i = 0, len = ids.length; i < len; i++) {
1785
- const id = ids[i];
1786
- __classPrivateFieldGet(this, _ids).add(id);
1787
- }
1788
- this.length = ids.length;
1789
- this._trigger("add", { items: ids });
1790
- }
1791
- else {
1792
- __classPrivateFieldSet(this, _data$1, new DataSet());
1793
- }
1794
- // subscribe to new dataset
1795
- if (__classPrivateFieldGet(this, _data$1).on) {
1796
- __classPrivateFieldGet(this, _data$1).on("*", __classPrivateFieldGet(this, _listener));
1797
- }
1798
- }
1799
- /**
1800
- * Refresh the DataView.
1801
- * Useful when the DataView has a filter function containing a variable parameter.
1802
- */
1803
- refresh() {
1804
- const ids = __classPrivateFieldGet(this, _data$1).getIds({
1805
- filter: __classPrivateFieldGet(this, _options$1).filter,
1806
- });
1807
- const oldIds = [...__classPrivateFieldGet(this, _ids)];
1808
- const newIds = {};
1809
- const addedIds = [];
1810
- const removedIds = [];
1811
- const removedItems = [];
1812
- // check for additions
1813
- for (let i = 0, len = ids.length; i < len; i++) {
1814
- const id = ids[i];
1815
- newIds[id] = true;
1816
- if (!__classPrivateFieldGet(this, _ids).has(id)) {
1817
- addedIds.push(id);
1818
- __classPrivateFieldGet(this, _ids).add(id);
1819
- }
1820
- }
1821
- // check for removals
1822
- for (let i = 0, len = oldIds.length; i < len; i++) {
1823
- const id = oldIds[i];
1824
- const item = __classPrivateFieldGet(this, _data$1).get(id);
1825
- if (item == null) {
1826
- // @TODO: Investigate.
1827
- // Doesn't happen during tests or examples.
1828
- // Is it really impossible or could it eventually happen?
1829
- // How to handle it if it does? The types guarantee non-nullable items.
1830
- console.error("If you see this, report it please.");
1831
- }
1832
- else if (!newIds[id]) {
1833
- removedIds.push(id);
1834
- removedItems.push(item);
1835
- __classPrivateFieldGet(this, _ids).delete(id);
1836
- }
1837
- }
1838
- this.length += addedIds.length - removedIds.length;
1839
- // trigger events
1840
- if (addedIds.length) {
1841
- this._trigger("add", { items: addedIds });
1842
- }
1843
- if (removedIds.length) {
1844
- this._trigger("remove", { items: removedIds, oldData: removedItems });
1845
- }
1846
- }
1847
- /** @inheritDoc */
1848
- get(first, second) {
1849
- if (__classPrivateFieldGet(this, _data$1) == null) {
1850
- return null;
1851
- }
1852
- // parse the arguments
1853
- let ids = null;
1854
- let options;
1855
- if (isId(first) || Array.isArray(first)) {
1856
- ids = first;
1857
- options = second;
1858
- }
1859
- else {
1860
- options = first;
1861
- }
1862
- // extend the options with the default options and provided options
1863
- const viewOptions = Object.assign({}, __classPrivateFieldGet(this, _options$1), options);
1864
- // create a combined filter method when needed
1865
- const thisFilter = __classPrivateFieldGet(this, _options$1).filter;
1866
- const optionsFilter = options && options.filter;
1867
- if (thisFilter && optionsFilter) {
1868
- viewOptions.filter = (item) => {
1869
- return thisFilter(item) && optionsFilter(item);
1870
- };
1871
- }
1872
- if (ids == null) {
1873
- return __classPrivateFieldGet(this, _data$1).get(viewOptions);
1874
- }
1875
- else {
1876
- return __classPrivateFieldGet(this, _data$1).get(ids, viewOptions);
1877
- }
1878
- }
1879
- /** @inheritDoc */
1880
- getIds(options) {
1881
- if (__classPrivateFieldGet(this, _data$1).length) {
1882
- const defaultFilter = __classPrivateFieldGet(this, _options$1).filter;
1883
- const optionsFilter = options != null ? options.filter : null;
1884
- let filter;
1885
- if (optionsFilter) {
1886
- if (defaultFilter) {
1887
- filter = (item) => {
1888
- return defaultFilter(item) && optionsFilter(item);
1889
- };
1890
- }
1891
- else {
1892
- filter = optionsFilter;
1893
- }
1894
- }
1895
- else {
1896
- filter = defaultFilter;
1897
- }
1898
- return __classPrivateFieldGet(this, _data$1).getIds({
1899
- filter: filter,
1900
- order: options && options.order,
1901
- });
1902
- }
1903
- else {
1904
- return [];
1905
- }
1906
- }
1907
- /** @inheritDoc */
1908
- forEach(callback, options) {
1909
- if (__classPrivateFieldGet(this, _data$1)) {
1910
- const defaultFilter = __classPrivateFieldGet(this, _options$1).filter;
1911
- const optionsFilter = options && options.filter;
1912
- let filter;
1913
- if (optionsFilter) {
1914
- if (defaultFilter) {
1915
- filter = function (item) {
1916
- return defaultFilter(item) && optionsFilter(item);
1917
- };
1918
- }
1919
- else {
1920
- filter = optionsFilter;
1921
- }
1922
- }
1923
- else {
1924
- filter = defaultFilter;
1925
- }
1926
- __classPrivateFieldGet(this, _data$1).forEach(callback, {
1927
- filter: filter,
1928
- order: options && options.order,
1929
- });
1930
- }
1931
- }
1932
- /** @inheritDoc */
1933
- map(callback, options) {
1934
- if (__classPrivateFieldGet(this, _data$1)) {
1935
- const defaultFilter = __classPrivateFieldGet(this, _options$1).filter;
1936
- const optionsFilter = options && options.filter;
1937
- let filter;
1938
- if (optionsFilter) {
1939
- if (defaultFilter) {
1940
- filter = (item) => {
1941
- return defaultFilter(item) && optionsFilter(item);
1942
- };
1943
- }
1944
- else {
1945
- filter = optionsFilter;
1946
- }
1947
- }
1948
- else {
1949
- filter = defaultFilter;
1950
- }
1951
- return __classPrivateFieldGet(this, _data$1).map(callback, {
1952
- filter: filter,
1953
- order: options && options.order,
1954
- });
1955
- }
1956
- else {
1957
- return [];
1958
- }
1959
- }
1960
- /** @inheritDoc */
1961
- getDataSet() {
1962
- return __classPrivateFieldGet(this, _data$1).getDataSet();
1963
- }
1964
- /** @inheritDoc */
1965
- stream(ids) {
1966
- return __classPrivateFieldGet(this, _data$1).stream(ids || {
1967
- [Symbol.iterator]: __classPrivateFieldGet(this, _ids).keys.bind(__classPrivateFieldGet(this, _ids)),
1968
- });
1969
- }
1970
- /**
1971
- * Render the instance unusable prior to garbage collection.
1972
- *
1973
- * @remarks
1974
- * The intention of this method is to help discover scenarios where the data
1975
- * view is being used when the programmer thinks it has been garbage collected
1976
- * already. It's stricter version of `dataView.setData(null)`.
1977
- */
1978
- dispose() {
1979
- var _a;
1980
- if ((_a = __classPrivateFieldGet(this, _data$1)) === null || _a === void 0 ? void 0 : _a.off) {
1981
- __classPrivateFieldGet(this, _data$1).off("*", __classPrivateFieldGet(this, _listener));
1982
- }
1983
- const message = "This data view has already been disposed of.";
1984
- const replacement = {
1985
- get: () => {
1986
- throw new Error(message);
1987
- },
1988
- set: () => {
1989
- throw new Error(message);
1990
- },
1991
- configurable: false,
1992
- };
1993
- for (const key of Reflect.ownKeys(DataView.prototype)) {
1994
- Object.defineProperty(this, key, replacement);
1995
- }
1996
- }
1997
- /**
1998
- * Event listener. Will propagate all events from the connected data set to the subscribers of the DataView, but will filter the items and only trigger when there are changes in the filtered data set.
1999
- *
2000
- * @param event - The name of the event.
2001
- * @param params - Parameters of the event.
2002
- * @param senderId - Id supplied by the sender.
2003
- */
2004
- _onEvent(event, params, senderId) {
2005
- if (!params || !params.items || !__classPrivateFieldGet(this, _data$1)) {
2006
- return;
2007
- }
2008
- const ids = params.items;
2009
- const addedIds = [];
2010
- const updatedIds = [];
2011
- const removedIds = [];
2012
- const oldItems = [];
2013
- const updatedItems = [];
2014
- const removedItems = [];
2015
- switch (event) {
2016
- case "add":
2017
- // filter the ids of the added items
2018
- for (let i = 0, len = ids.length; i < len; i++) {
2019
- const id = ids[i];
2020
- const item = this.get(id);
2021
- if (item) {
2022
- __classPrivateFieldGet(this, _ids).add(id);
2023
- addedIds.push(id);
2024
- }
2025
- }
2026
- break;
2027
- case "update":
2028
- // determine the event from the views viewpoint: an updated
2029
- // item can be added, updated, or removed from this view.
2030
- for (let i = 0, len = ids.length; i < len; i++) {
2031
- const id = ids[i];
2032
- const item = this.get(id);
2033
- if (item) {
2034
- if (__classPrivateFieldGet(this, _ids).has(id)) {
2035
- updatedIds.push(id);
2036
- updatedItems.push(params.data[i]);
2037
- oldItems.push(params.oldData[i]);
2038
- }
2039
- else {
2040
- __classPrivateFieldGet(this, _ids).add(id);
2041
- addedIds.push(id);
2042
- }
2043
- }
2044
- else {
2045
- if (__classPrivateFieldGet(this, _ids).has(id)) {
2046
- __classPrivateFieldGet(this, _ids).delete(id);
2047
- removedIds.push(id);
2048
- removedItems.push(params.oldData[i]);
2049
- }
2050
- }
2051
- }
2052
- break;
2053
- case "remove":
2054
- // filter the ids of the removed items
2055
- for (let i = 0, len = ids.length; i < len; i++) {
2056
- const id = ids[i];
2057
- if (__classPrivateFieldGet(this, _ids).has(id)) {
2058
- __classPrivateFieldGet(this, _ids).delete(id);
2059
- removedIds.push(id);
2060
- removedItems.push(params.oldData[i]);
2061
- }
2062
- }
2063
- break;
2064
- }
2065
- this.length += addedIds.length - removedIds.length;
2066
- if (addedIds.length) {
2067
- this._trigger("add", { items: addedIds }, senderId);
2068
- }
2069
- if (updatedIds.length) {
2070
- this._trigger("update", { items: updatedIds, oldData: oldItems, data: updatedItems }, senderId);
2071
- }
2072
- if (removedIds.length) {
2073
- this._trigger("remove", { items: removedIds, oldData: removedItems }, senderId);
2074
- }
2075
- }
2076
- }
2077
- _listener = new WeakMap(), _data$1 = new WeakMap(), _ids = new WeakMap(), _options$1 = new WeakMap();
1977
+ /**
1978
+ * Check that given value is compatible with Vis Data Set interface.
1979
+ *
1980
+ * @param idProp - The expected property to contain item id.
1981
+ * @param v - The value to be tested.
1982
+ * @returns True if all expected values and methods match, false otherwise.
1983
+ */
1984
+ function isDataSetLike(idProp, v) {
1985
+ return (typeof v === "object" &&
1986
+ v !== null &&
1987
+ idProp === v.idProp &&
1988
+ typeof v.add === "function" &&
1989
+ typeof v.clear === "function" &&
1990
+ typeof v.distinct === "function" &&
1991
+ typeof v.forEach === "function" &&
1992
+ typeof v.get === "function" &&
1993
+ typeof v.getDataSet === "function" &&
1994
+ typeof v.getIds === "function" &&
1995
+ typeof v.length === "number" &&
1996
+ typeof v.map === "function" &&
1997
+ typeof v.max === "function" &&
1998
+ typeof v.min === "function" &&
1999
+ typeof v.off === "function" &&
2000
+ typeof v.on === "function" &&
2001
+ typeof v.remove === "function" &&
2002
+ typeof v.setOptions === "function" &&
2003
+ typeof v.stream === "function" &&
2004
+ typeof v.update === "function" &&
2005
+ typeof v.updateOnly === "function");
2006
+ }
2078
2007
 
2079
- /**
2080
- * Check that given value is compatible with Vis Data Set interface.
2081
- *
2082
- * @param idProp - The expected property to contain item id.
2083
- * @param v - The value to be tested.
2084
- *
2085
- * @returns True if all expected values and methods match, false otherwise.
2086
- */
2087
- function isDataSetLike(idProp, v) {
2088
- return (typeof v === "object" &&
2089
- v !== null &&
2090
- idProp === v.idProp &&
2091
- typeof v.add === "function" &&
2092
- typeof v.clear === "function" &&
2093
- typeof v.distinct === "function" &&
2094
- typeof v.forEach === "function" &&
2095
- typeof v.get === "function" &&
2096
- typeof v.getDataSet === "function" &&
2097
- typeof v.getIds === "function" &&
2098
- typeof v.length === "number" &&
2099
- typeof v.map === "function" &&
2100
- typeof v.max === "function" &&
2101
- typeof v.min === "function" &&
2102
- typeof v.off === "function" &&
2103
- typeof v.on === "function" &&
2104
- typeof v.remove === "function" &&
2105
- typeof v.setOptions === "function" &&
2106
- typeof v.stream === "function" &&
2107
- typeof v.update === "function" &&
2108
- typeof v.updateOnly === "function");
2109
- }
2008
+ /**
2009
+ * Check that given value is compatible with Vis Data View interface.
2010
+ *
2011
+ * @param idProp - The expected property to contain item id.
2012
+ * @param v - The value to be tested.
2013
+ * @returns True if all expected values and methods match, false otherwise.
2014
+ */
2015
+ function isDataViewLike(idProp, v) {
2016
+ return (typeof v === "object" &&
2017
+ v !== null &&
2018
+ idProp === v.idProp &&
2019
+ typeof v.forEach === "function" &&
2020
+ typeof v.get === "function" &&
2021
+ typeof v.getDataSet === "function" &&
2022
+ typeof v.getIds === "function" &&
2023
+ typeof v.length === "number" &&
2024
+ typeof v.map === "function" &&
2025
+ typeof v.off === "function" &&
2026
+ typeof v.on === "function" &&
2027
+ typeof v.stream === "function" &&
2028
+ isDataSetLike(idProp, v.getDataSet()));
2029
+ }
2110
2030
 
2111
- /**
2112
- * Check that given value is compatible with Vis Data View interface.
2113
- *
2114
- * @param idProp - The expected property to contain item id.
2115
- * @param v - The value to be tested.
2116
- *
2117
- * @returns True if all expected values and methods match, false otherwise.
2118
- */
2119
- function isDataViewLike(idProp, v) {
2120
- return (typeof v === "object" &&
2121
- v !== null &&
2122
- idProp === v.idProp &&
2123
- typeof v.forEach === "function" &&
2124
- typeof v.get === "function" &&
2125
- typeof v.getDataSet === "function" &&
2126
- typeof v.getIds === "function" &&
2127
- typeof v.length === "number" &&
2128
- typeof v.map === "function" &&
2129
- typeof v.off === "function" &&
2130
- typeof v.on === "function" &&
2131
- typeof v.stream === "function" &&
2132
- isDataSetLike(idProp, v.getDataSet()));
2133
- }
2031
+ Object.defineProperty(exports, 'DELETE', {
2032
+ enumerable: true,
2033
+ get: function () { return esnext.DELETE; }
2034
+ });
2035
+ exports.DataSet = DataSet;
2036
+ exports.DataStream = DataStream;
2037
+ exports.DataView = DataView;
2038
+ exports.Queue = Queue;
2039
+ exports.createNewDataPipeFrom = createNewDataPipeFrom;
2040
+ exports.isDataSetLike = isDataSetLike;
2041
+ exports.isDataViewLike = isDataViewLike;
2134
2042
 
2135
- Object.defineProperty(exports, 'DELETE', {
2136
- enumerable: true,
2137
- get: function () {
2138
- return esnext.DELETE;
2139
- }
2140
- });
2141
- exports.DataSet = DataSet;
2142
- exports.DataStream = DataStream;
2143
- exports.DataView = DataView;
2144
- exports.Queue = Queue;
2145
- exports.createNewDataPipeFrom = createNewDataPipeFrom;
2146
- exports.isDataSetLike = isDataSetLike;
2147
- exports.isDataViewLike = isDataViewLike;
2043
+ Object.defineProperty(exports, '__esModule', { value: true });
2148
2044
 
2149
- Object.defineProperty(exports, '__esModule', { value: true });
2150
-
2151
- })));
2045
+ }));
2152
2046
  //# sourceMappingURL=vis-data.js.map