@speclynx/apidom-datamodel 4.0.1 → 4.0.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 (95) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/package.json +4 -5
  3. package/src/KeyValuePair.cjs +31 -0
  4. package/src/KeyValuePair.mjs +27 -0
  5. package/src/KeyValuePair.ts +31 -0
  6. package/src/Metadata.cjs +91 -0
  7. package/src/Metadata.mjs +87 -0
  8. package/src/Metadata.ts +100 -0
  9. package/src/Namespace.cjs +212 -0
  10. package/src/Namespace.mjs +206 -0
  11. package/src/Namespace.ts +260 -0
  12. package/src/ObjectSlice.cjs +199 -0
  13. package/src/ObjectSlice.mjs +195 -0
  14. package/src/ObjectSlice.ts +228 -0
  15. package/src/clone/errors/CloneError.cjs +22 -0
  16. package/src/clone/errors/CloneError.mjs +19 -0
  17. package/src/clone/errors/CloneError.ts +26 -0
  18. package/src/clone/errors/DeepCloneError.cjs +11 -0
  19. package/src/clone/errors/DeepCloneError.mjs +6 -0
  20. package/src/clone/errors/DeepCloneError.ts +8 -0
  21. package/src/clone/errors/ShallowCloneError.cjs +11 -0
  22. package/src/clone/errors/ShallowCloneError.mjs +6 -0
  23. package/src/clone/errors/ShallowCloneError.ts +8 -0
  24. package/src/clone/index.cjs +188 -0
  25. package/src/clone/index.mjs +178 -0
  26. package/src/clone/index.ts +195 -0
  27. package/src/elements/Annotation.cjs +35 -0
  28. package/src/elements/Annotation.mjs +30 -0
  29. package/src/elements/Annotation.ts +35 -0
  30. package/src/elements/Comment.cjs +18 -0
  31. package/src/elements/Comment.mjs +13 -0
  32. package/src/elements/Comment.ts +16 -0
  33. package/src/elements/LinkElement.cjs +50 -0
  34. package/src/elements/LinkElement.mjs +45 -0
  35. package/src/elements/LinkElement.ts +49 -0
  36. package/src/elements/ParseResult.cjs +91 -0
  37. package/src/elements/ParseResult.mjs +86 -0
  38. package/src/elements/ParseResult.ts +94 -0
  39. package/src/elements/RefElement.cjs +34 -0
  40. package/src/elements/RefElement.mjs +29 -0
  41. package/src/elements/RefElement.ts +33 -0
  42. package/src/elements/SourceMap.cjs +140 -0
  43. package/src/elements/SourceMap.mjs +134 -0
  44. package/src/elements/SourceMap.ts +170 -0
  45. package/src/elements/Style.cjs +54 -0
  46. package/src/elements/Style.mjs +48 -0
  47. package/src/elements/Style.ts +56 -0
  48. package/src/index.cjs +58 -0
  49. package/src/index.mjs +11 -0
  50. package/src/index.ts +79 -0
  51. package/src/predicates/elements.cjs +46 -0
  52. package/src/predicates/elements.mjs +35 -0
  53. package/src/predicates/elements.ts +42 -0
  54. package/src/predicates/index.cjs +77 -0
  55. package/src/predicates/index.mjs +56 -0
  56. package/src/predicates/index.ts +89 -0
  57. package/src/predicates/primitives.cjs +69 -0
  58. package/src/predicates/primitives.mjs +56 -0
  59. package/src/predicates/primitives.ts +79 -0
  60. package/src/primitives/ArrayElement.cjs +155 -0
  61. package/src/primitives/ArrayElement.mjs +148 -0
  62. package/src/primitives/ArrayElement.ts +161 -0
  63. package/src/primitives/BooleanElement.cjs +20 -0
  64. package/src/primitives/BooleanElement.mjs +15 -0
  65. package/src/primitives/BooleanElement.ts +18 -0
  66. package/src/primitives/CollectionElement.cjs +180 -0
  67. package/src/primitives/CollectionElement.mjs +173 -0
  68. package/src/primitives/CollectionElement.ts +191 -0
  69. package/src/primitives/Element.cjs +510 -0
  70. package/src/primitives/Element.mjs +505 -0
  71. package/src/primitives/Element.ts +556 -0
  72. package/src/primitives/MemberElement.cjs +58 -0
  73. package/src/primitives/MemberElement.mjs +53 -0
  74. package/src/primitives/MemberElement.ts +61 -0
  75. package/src/primitives/NullElement.cjs +28 -0
  76. package/src/primitives/NullElement.mjs +23 -0
  77. package/src/primitives/NullElement.ts +26 -0
  78. package/src/primitives/NumberElement.cjs +20 -0
  79. package/src/primitives/NumberElement.mjs +15 -0
  80. package/src/primitives/NumberElement.ts +18 -0
  81. package/src/primitives/ObjectElement.cjs +220 -0
  82. package/src/primitives/ObjectElement.mjs +214 -0
  83. package/src/primitives/ObjectElement.ts +263 -0
  84. package/src/primitives/StringElement.cjs +27 -0
  85. package/src/primitives/StringElement.mjs +22 -0
  86. package/src/primitives/StringElement.ts +25 -0
  87. package/src/registration.cjs +101 -0
  88. package/src/registration.mjs +79 -0
  89. package/src/registration.ts +111 -0
  90. package/src/serialisers/JSONSerialiser.cjs +230 -0
  91. package/src/serialisers/JSONSerialiser.mjs +221 -0
  92. package/src/serialisers/JSONSerialiser.ts +295 -0
  93. package/src/types.cjs +3 -0
  94. package/src/types.mjs +1 -0
  95. package/src/types.ts +72 -0
@@ -0,0 +1,148 @@
1
+ import CollectionElement from "./CollectionElement.mjs"; // Re-export types from CollectionElement
2
+ /**
3
+ * ArrayElement represents an array/collection of elements in ApiDOM.
4
+ *
5
+ * @typeParam T - The element type contained in the array, defaults to Element
6
+ * @public
7
+ */
8
+ class ArrayElement extends CollectionElement {
9
+ constructor(content, meta, attributes) {
10
+ super(content || [], meta, attributes);
11
+ this.element = 'array';
12
+ }
13
+ primitive() {
14
+ return 'array';
15
+ }
16
+
17
+ /**
18
+ * Gets the element at the specified index.
19
+ */
20
+ get(index) {
21
+ return this._content[index];
22
+ }
23
+
24
+ /**
25
+ * Helper for returning the value of an item.
26
+ */
27
+ getValue(index) {
28
+ const item = this.get(index);
29
+ if (item) {
30
+ return item.toValue();
31
+ }
32
+ return undefined;
33
+ }
34
+
35
+ /**
36
+ * Sets the element at the specified index, or sets the content if called with one argument.
37
+ */
38
+ set(indexOrContent, value) {
39
+ if (typeof indexOrContent === 'number' && value !== undefined) {
40
+ this._content[indexOrContent] = this.refract(value);
41
+ } else {
42
+ // Delegate to parent set behavior
43
+ this.content = indexOrContent;
44
+ }
45
+ return this;
46
+ }
47
+
48
+ /**
49
+ * Removes the element at the specified index.
50
+ */
51
+ remove(index) {
52
+ return this._content.splice(index, 1)[0] ?? null;
53
+ }
54
+
55
+ /**
56
+ * Maps each element using the provided callback function.
57
+ */
58
+ map(callback, thisArg) {
59
+ return this._content.map(callback, thisArg);
60
+ }
61
+
62
+ /**
63
+ * Maps and then flattens the results.
64
+ */
65
+ flatMap(callback, thisArg) {
66
+ return this._content.flatMap(callback, thisArg);
67
+ }
68
+
69
+ /**
70
+ * Returns an array containing the truthy results of calling the given transformation.
71
+ */
72
+ compactMap(transform, thisArg) {
73
+ const results = [];
74
+ for (const element of this._content) {
75
+ const result = transform.call(thisArg, element);
76
+ if (result) {
77
+ results.push(result);
78
+ }
79
+ }
80
+ return results;
81
+ }
82
+
83
+ /**
84
+ * Filters elements using the provided callback.
85
+ */
86
+ filter(callback, thisArg) {
87
+ const filtered = this._content.filter(callback, thisArg);
88
+ return new this.constructor(filtered);
89
+ }
90
+
91
+ /**
92
+ * Rejects elements that match the provided callback.
93
+ */
94
+ reject(callback, thisArg) {
95
+ const results = [];
96
+ for (const element of this._content) {
97
+ if (!callback.call(thisArg, element)) {
98
+ results.push(element);
99
+ }
100
+ }
101
+ return new this.constructor(results);
102
+ }
103
+
104
+ /**
105
+ * Reduces the array to a single value.
106
+ * This is a reduce function specifically for datamodel arrays and objects.
107
+ * It allows for returning normal values or datamodel instances.
108
+ */
109
+ reduce(callback, initialValue) {
110
+ let startIndex;
111
+ let memo;
112
+
113
+ // Allows for defining a starting value of the reduce
114
+ if (initialValue !== undefined) {
115
+ startIndex = 0;
116
+ memo = this.refract(initialValue);
117
+ } else {
118
+ startIndex = 1;
119
+ memo = this.first;
120
+ }
121
+
122
+ // Sending each function call to the registry allows for passing datamodel
123
+ // instances through the function return.
124
+ for (let i = startIndex; i < this.length; i += 1) {
125
+ const item = this._content[i];
126
+ const result = callback(memo, item, i, this);
127
+ memo = result === undefined ? result : this.refract(result);
128
+ }
129
+ return memo;
130
+ }
131
+
132
+ /**
133
+ * Executes a provided function once for each element.
134
+ */
135
+ forEach(callback, thisArg) {
136
+ this._content.forEach((item, index) => {
137
+ callback.call(thisArg, item, index);
138
+ });
139
+ }
140
+
141
+ /**
142
+ * Returns an empty array element.
143
+ */
144
+ empty() {
145
+ return new this.constructor([]);
146
+ }
147
+ }
148
+ export default ArrayElement;
@@ -0,0 +1,161 @@
1
+ import CollectionElement from './CollectionElement.ts';
2
+ import type Element from './Element.ts';
3
+ import type { Meta, Attributes } from './Element.ts';
4
+
5
+ // Re-export types from CollectionElement
6
+ export type { FindCondition, FindOptions } from './CollectionElement.ts';
7
+
8
+ /**
9
+ * ArrayElement represents an array/collection of elements in ApiDOM.
10
+ *
11
+ * @typeParam T - The element type contained in the array, defaults to Element
12
+ * @public
13
+ */
14
+ class ArrayElement<T extends Element = Element> extends CollectionElement<T> {
15
+ constructor(content?: unknown[], meta?: Meta, attributes?: Attributes) {
16
+ super(content || [], meta, attributes);
17
+ this.element = 'array';
18
+ }
19
+
20
+ primitive(): string {
21
+ return 'array';
22
+ }
23
+
24
+ /**
25
+ * Gets the element at the specified index.
26
+ */
27
+ get(index: number): T | undefined {
28
+ return this._content[index];
29
+ }
30
+
31
+ /**
32
+ * Helper for returning the value of an item.
33
+ */
34
+ getValue(index: number): unknown {
35
+ const item = this.get(index);
36
+
37
+ if (item) {
38
+ return item.toValue();
39
+ }
40
+
41
+ return undefined;
42
+ }
43
+
44
+ /**
45
+ * Sets the element at the specified index, or sets the content if called with one argument.
46
+ */
47
+ set(indexOrContent: number | unknown, value?: unknown): this {
48
+ if (typeof indexOrContent === 'number' && value !== undefined) {
49
+ this._content[indexOrContent] = this.refract(value) as T;
50
+ } else {
51
+ // Delegate to parent set behavior
52
+ this.content = indexOrContent;
53
+ }
54
+ return this;
55
+ }
56
+
57
+ /**
58
+ * Removes the element at the specified index.
59
+ */
60
+ remove(index: number): T | null {
61
+ return this._content.splice(index, 1)[0] ?? null;
62
+ }
63
+
64
+ /**
65
+ * Maps each element using the provided callback function.
66
+ */
67
+ map<U>(callback: (element: T, index: number, array: T[]) => U, thisArg?: unknown): U[] {
68
+ return this._content.map(callback, thisArg);
69
+ }
70
+
71
+ /**
72
+ * Maps and then flattens the results.
73
+ */
74
+ flatMap<U>(callback: (element: T, index: number, array: T[]) => U | U[], thisArg?: unknown): U[] {
75
+ return this._content.flatMap(callback, thisArg);
76
+ }
77
+
78
+ /**
79
+ * Returns an array containing the truthy results of calling the given transformation.
80
+ */
81
+ compactMap<U>(transform: (element: T) => U | undefined | null, thisArg?: unknown): U[] {
82
+ const results: U[] = [];
83
+
84
+ for (const element of this._content) {
85
+ const result = transform.call(thisArg, element);
86
+ if (result) {
87
+ results.push(result);
88
+ }
89
+ }
90
+
91
+ return results;
92
+ }
93
+
94
+ /**
95
+ * Filters elements using the provided callback.
96
+ */
97
+ filter(callback: (element: T) => boolean, thisArg?: unknown): ArrayElement<T> {
98
+ const filtered = this._content.filter(callback, thisArg);
99
+ return new (this.constructor as new (content: T[]) => ArrayElement<T>)(filtered);
100
+ }
101
+
102
+ /**
103
+ * Rejects elements that match the provided callback.
104
+ */
105
+ reject(callback: (element: T) => boolean, thisArg?: unknown): ArrayElement<T> {
106
+ const results: T[] = [];
107
+ for (const element of this._content) {
108
+ if (!callback.call(thisArg, element)) {
109
+ results.push(element);
110
+ }
111
+ }
112
+ return new (this.constructor as new (content: T[]) => ArrayElement<T>)(results);
113
+ }
114
+
115
+ /**
116
+ * Reduces the array to a single value.
117
+ * This is a reduce function specifically for datamodel arrays and objects.
118
+ * It allows for returning normal values or datamodel instances.
119
+ */
120
+ reduce<U>(callback: (memo: U, item: T, index: number, arr: this) => U, initialValue?: U): U {
121
+ let startIndex: number;
122
+ let memo: U;
123
+
124
+ // Allows for defining a starting value of the reduce
125
+ if (initialValue !== undefined) {
126
+ startIndex = 0;
127
+ memo = this.refract(initialValue) as unknown as U;
128
+ } else {
129
+ startIndex = 1;
130
+ memo = this.first as unknown as U;
131
+ }
132
+
133
+ // Sending each function call to the registry allows for passing datamodel
134
+ // instances through the function return.
135
+ for (let i = startIndex; i < this.length; i += 1) {
136
+ const item = this._content[i];
137
+ const result = callback(memo, item, i, this);
138
+ memo = result === undefined ? result : (this.refract(result) as unknown as U);
139
+ }
140
+
141
+ return memo;
142
+ }
143
+
144
+ /**
145
+ * Executes a provided function once for each element.
146
+ */
147
+ forEach(callback: (element: T, index: number) => void, thisArg?: unknown): void {
148
+ this._content.forEach((item, index) => {
149
+ callback.call(thisArg, item, index);
150
+ });
151
+ }
152
+
153
+ /**
154
+ * Returns an empty array element.
155
+ */
156
+ empty(): this {
157
+ return new (this.constructor as new (content: unknown[]) => this)([]);
158
+ }
159
+ }
160
+
161
+ export default ArrayElement;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
+ exports.__esModule = true;
5
+ exports.default = void 0;
6
+ var _Element = _interopRequireDefault(require("./Element.cjs"));
7
+ /**
8
+ * BooleanElement represents a boolean value in ApiDOM.
9
+ * @public
10
+ */
11
+ class BooleanElement extends _Element.default {
12
+ constructor(content, meta, attributes) {
13
+ super(content, meta, attributes);
14
+ this.element = 'boolean';
15
+ }
16
+ primitive() {
17
+ return 'boolean';
18
+ }
19
+ }
20
+ var _default = exports.default = BooleanElement;
@@ -0,0 +1,15 @@
1
+ import Element from "./Element.mjs";
2
+ /**
3
+ * BooleanElement represents a boolean value in ApiDOM.
4
+ * @public
5
+ */
6
+ class BooleanElement extends Element {
7
+ constructor(content, meta, attributes) {
8
+ super(content, meta, attributes);
9
+ this.element = 'boolean';
10
+ }
11
+ primitive() {
12
+ return 'boolean';
13
+ }
14
+ }
15
+ export default BooleanElement;
@@ -0,0 +1,18 @@
1
+ import Element, { type Meta, type Attributes } from './Element.ts';
2
+
3
+ /**
4
+ * BooleanElement represents a boolean value in ApiDOM.
5
+ * @public
6
+ */
7
+ class BooleanElement extends Element {
8
+ constructor(content?: boolean, meta?: Meta, attributes?: Attributes) {
9
+ super(content, meta, attributes);
10
+ this.element = 'boolean';
11
+ }
12
+
13
+ primitive(): string {
14
+ return 'boolean';
15
+ }
16
+ }
17
+
18
+ export default BooleanElement;
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
+ exports.__esModule = true;
5
+ exports.default = void 0;
6
+ var _Element = _interopRequireDefault(require("./Element.cjs"));
7
+ /**
8
+ * Condition function for finding elements.
9
+ * @public
10
+ */
11
+
12
+ /**
13
+ * Options for finding elements.
14
+ * @public
15
+ */
16
+
17
+ /**
18
+ * CollectionElement is an abstract base class for collection-like elements.
19
+ * Both ArrayElement and ObjectElement extend this class.
20
+ *
21
+ * This class contains the shared functionality between arrays and objects,
22
+ * while keeping the conflicting methods (get, set, remove, map, filter, etc.)
23
+ * in the respective subclasses.
24
+ *
25
+ * @remarks
26
+ * This is primarily an implementation detail. Use ArrayElement or ObjectElement directly.
27
+ *
28
+ * @typeParam T - The element type contained in the collection, defaults to Element
29
+ * @public
30
+ */
31
+ class CollectionElement extends _Element.default {
32
+ constructor(content, meta, attributes) {
33
+ super(content || [], meta, attributes);
34
+ }
35
+
36
+ /**
37
+ * Returns the length of the collection.
38
+ */
39
+ get length() {
40
+ return this._content.length;
41
+ }
42
+
43
+ /**
44
+ * Returns whether the collection is empty.
45
+ */
46
+ get isEmpty() {
47
+ return this.length === 0;
48
+ }
49
+
50
+ /**
51
+ * Return the first item in the collection.
52
+ */
53
+ get first() {
54
+ return this._content[0];
55
+ }
56
+
57
+ /**
58
+ * Return the second item in the collection.
59
+ */
60
+ get second() {
61
+ return this._content[1];
62
+ }
63
+
64
+ /**
65
+ * Return the last item in the collection.
66
+ */
67
+ get last() {
68
+ return this._content.at(-1);
69
+ }
70
+
71
+ /**
72
+ * Adds the given elements to the end of the collection.
73
+ */
74
+ push(...values) {
75
+ for (const value of values) {
76
+ this._content.push(this.refract(value));
77
+ }
78
+ return this;
79
+ }
80
+
81
+ /**
82
+ * Removes the first element from the collection.
83
+ */
84
+ shift() {
85
+ return this._content.shift();
86
+ }
87
+
88
+ /**
89
+ * Adds the given element to the beginning of the collection.
90
+ */
91
+ unshift(value) {
92
+ this._content.unshift(this.refract(value));
93
+ }
94
+
95
+ /**
96
+ * Looks for matching children using deep equality.
97
+ */
98
+ includes(value) {
99
+ return this._content.some(element => element.equals(value));
100
+ }
101
+
102
+ /**
103
+ * Recursively search all descendants using a condition function.
104
+ */
105
+ findElements(condition, givenOptions) {
106
+ const options = givenOptions || {};
107
+ const recursive = !!options.recursive;
108
+ const results = options.results === undefined ? [] : options.results;
109
+ for (let i = 0; i < this._content.length; i += 1) {
110
+ const item = this._content[i];
111
+
112
+ // We use duck-typing here to support any registered class that
113
+ // may contain other elements.
114
+
115
+ const itemWithFindElements = item;
116
+ if (recursive && typeof itemWithFindElements.findElements === 'function') {
117
+ itemWithFindElements.findElements(condition, {
118
+ results,
119
+ recursive
120
+ });
121
+ }
122
+ if (condition(item, i, undefined)) {
123
+ results.push(item);
124
+ }
125
+ }
126
+ return results;
127
+ }
128
+
129
+ /**
130
+ * Recursively search all descendants using a condition function.
131
+ */
132
+ find(condition) {
133
+ const results = this.findElements(condition, {
134
+ recursive: true
135
+ });
136
+ return new this.ArrayElement(results);
137
+ }
138
+
139
+ /**
140
+ * Find elements by their element type name.
141
+ */
142
+ findByElement(element) {
143
+ return this.find(item => item.element === element);
144
+ }
145
+
146
+ /**
147
+ * Find elements by class name.
148
+ */
149
+ findByClass(className) {
150
+ return this.find(item => {
151
+ const classes = item.classes;
152
+ return typeof classes.includes === 'function' && classes.includes(className);
153
+ });
154
+ }
155
+
156
+ /**
157
+ * Search the tree recursively and find the element with the matching ID.
158
+ */
159
+ getById(id) {
160
+ return this.find(item => item.id === id).first;
161
+ }
162
+
163
+ /**
164
+ * Returns an empty collection element.
165
+ */
166
+
167
+ /**
168
+ * Concatenates two collection elements.
169
+ */
170
+ concat(other) {
171
+ const Ctor = this.constructor;
172
+ return new Ctor(this._content.concat(other._content));
173
+ }
174
+
175
+ // Iterator support
176
+ [Symbol.iterator]() {
177
+ return this._content[Symbol.iterator]();
178
+ }
179
+ }
180
+ var _default = exports.default = CollectionElement;
@@ -0,0 +1,173 @@
1
+ import Element from "./Element.mjs";
2
+ /**
3
+ * Condition function for finding elements.
4
+ * @public
5
+ */
6
+ /**
7
+ * Options for finding elements.
8
+ * @public
9
+ */
10
+ /**
11
+ * CollectionElement is an abstract base class for collection-like elements.
12
+ * Both ArrayElement and ObjectElement extend this class.
13
+ *
14
+ * This class contains the shared functionality between arrays and objects,
15
+ * while keeping the conflicting methods (get, set, remove, map, filter, etc.)
16
+ * in the respective subclasses.
17
+ *
18
+ * @remarks
19
+ * This is primarily an implementation detail. Use ArrayElement or ObjectElement directly.
20
+ *
21
+ * @typeParam T - The element type contained in the collection, defaults to Element
22
+ * @public
23
+ */
24
+ class CollectionElement extends Element {
25
+ constructor(content, meta, attributes) {
26
+ super(content || [], meta, attributes);
27
+ }
28
+
29
+ /**
30
+ * Returns the length of the collection.
31
+ */
32
+ get length() {
33
+ return this._content.length;
34
+ }
35
+
36
+ /**
37
+ * Returns whether the collection is empty.
38
+ */
39
+ get isEmpty() {
40
+ return this.length === 0;
41
+ }
42
+
43
+ /**
44
+ * Return the first item in the collection.
45
+ */
46
+ get first() {
47
+ return this._content[0];
48
+ }
49
+
50
+ /**
51
+ * Return the second item in the collection.
52
+ */
53
+ get second() {
54
+ return this._content[1];
55
+ }
56
+
57
+ /**
58
+ * Return the last item in the collection.
59
+ */
60
+ get last() {
61
+ return this._content.at(-1);
62
+ }
63
+
64
+ /**
65
+ * Adds the given elements to the end of the collection.
66
+ */
67
+ push(...values) {
68
+ for (const value of values) {
69
+ this._content.push(this.refract(value));
70
+ }
71
+ return this;
72
+ }
73
+
74
+ /**
75
+ * Removes the first element from the collection.
76
+ */
77
+ shift() {
78
+ return this._content.shift();
79
+ }
80
+
81
+ /**
82
+ * Adds the given element to the beginning of the collection.
83
+ */
84
+ unshift(value) {
85
+ this._content.unshift(this.refract(value));
86
+ }
87
+
88
+ /**
89
+ * Looks for matching children using deep equality.
90
+ */
91
+ includes(value) {
92
+ return this._content.some(element => element.equals(value));
93
+ }
94
+
95
+ /**
96
+ * Recursively search all descendants using a condition function.
97
+ */
98
+ findElements(condition, givenOptions) {
99
+ const options = givenOptions || {};
100
+ const recursive = !!options.recursive;
101
+ const results = options.results === undefined ? [] : options.results;
102
+ for (let i = 0; i < this._content.length; i += 1) {
103
+ const item = this._content[i];
104
+
105
+ // We use duck-typing here to support any registered class that
106
+ // may contain other elements.
107
+
108
+ const itemWithFindElements = item;
109
+ if (recursive && typeof itemWithFindElements.findElements === 'function') {
110
+ itemWithFindElements.findElements(condition, {
111
+ results,
112
+ recursive
113
+ });
114
+ }
115
+ if (condition(item, i, undefined)) {
116
+ results.push(item);
117
+ }
118
+ }
119
+ return results;
120
+ }
121
+
122
+ /**
123
+ * Recursively search all descendants using a condition function.
124
+ */
125
+ find(condition) {
126
+ const results = this.findElements(condition, {
127
+ recursive: true
128
+ });
129
+ return new this.ArrayElement(results);
130
+ }
131
+
132
+ /**
133
+ * Find elements by their element type name.
134
+ */
135
+ findByElement(element) {
136
+ return this.find(item => item.element === element);
137
+ }
138
+
139
+ /**
140
+ * Find elements by class name.
141
+ */
142
+ findByClass(className) {
143
+ return this.find(item => {
144
+ const classes = item.classes;
145
+ return typeof classes.includes === 'function' && classes.includes(className);
146
+ });
147
+ }
148
+
149
+ /**
150
+ * Search the tree recursively and find the element with the matching ID.
151
+ */
152
+ getById(id) {
153
+ return this.find(item => item.id === id).first;
154
+ }
155
+
156
+ /**
157
+ * Returns an empty collection element.
158
+ */
159
+
160
+ /**
161
+ * Concatenates two collection elements.
162
+ */
163
+ concat(other) {
164
+ const Ctor = this.constructor;
165
+ return new Ctor(this._content.concat(other._content));
166
+ }
167
+
168
+ // Iterator support
169
+ [Symbol.iterator]() {
170
+ return this._content[Symbol.iterator]();
171
+ }
172
+ }
173
+ export default CollectionElement;