@vorplex/core 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/consts/mime-type.const.d.ts +456 -0
- package/dist/consts/mime-type.const.js +456 -0
- package/dist/consts/unit.const.d.ts +22 -0
- package/dist/consts/unit.const.js +22 -0
- package/dist/functions/debounce.function.d.ts +1 -0
- package/dist/functions/debounce.function.js +12 -0
- package/dist/functions/is-node-environment.function.d.ts +1 -0
- package/dist/functions/is-node-environment.function.js +3 -0
- package/dist/functions/parse-path-selector.function.d.ts +2 -0
- package/dist/functions/parse-path-selector.function.js +17 -0
- package/dist/functions/parse-url.function.d.ts +12 -0
- package/dist/functions/parse-url.function.js +25 -0
- package/dist/index.d.ts +92 -0
- package/dist/index.js +93 -0
- package/dist/interfaces/group.interface.d.ts +4 -0
- package/dist/interfaces/group.interface.js +0 -0
- package/dist/interfaces/key-value.interface.d.ts +4 -0
- package/dist/interfaces/key-value.interface.js +0 -0
- package/dist/modules/api/socket.model.d.ts +26 -0
- package/dist/modules/api/socket.model.js +66 -0
- package/dist/modules/api/web-client.model.d.ts +16 -0
- package/dist/modules/api/web-client.model.js +34 -0
- package/dist/modules/array/array.util.d.ts +17 -0
- package/dist/modules/array/array.util.js +105 -0
- package/dist/modules/changes/changes.util.d.ts +45 -0
- package/dist/modules/changes/changes.util.js +330 -0
- package/dist/modules/color/color-data.interface.d.ts +10 -0
- package/dist/modules/color/color-data.interface.js +0 -0
- package/dist/modules/color/color-formats.const.d.ts +9 -0
- package/dist/modules/color/color-formats.const.js +8 -0
- package/dist/modules/color/color.type.d.ts +4 -0
- package/dist/modules/color/color.type.js +0 -0
- package/dist/modules/color/color.util.d.ts +41 -0
- package/dist/modules/color/color.util.js +327 -0
- package/dist/modules/color/colors.const.d.ts +151 -0
- package/dist/modules/color/colors.const.js +150 -0
- package/dist/modules/color/hsl.interface.d.ts +6 -0
- package/dist/modules/color/hsl.interface.js +0 -0
- package/dist/modules/color/hsv.interface.d.ts +6 -0
- package/dist/modules/color/hsv.interface.js +0 -0
- package/dist/modules/color/rgb.interface.d.ts +6 -0
- package/dist/modules/color/rgb.interface.js +0 -0
- package/dist/modules/compression/compression.util.d.ts +4 -0
- package/dist/modules/compression/compression.util.js +52 -0
- package/dist/modules/date/date.util.d.ts +37 -0
- package/dist/modules/date/date.util.js +84 -0
- package/dist/modules/enum/enum.util.d.ts +17 -0
- package/dist/modules/enum/enum.util.js +69 -0
- package/dist/modules/hash/hash.util.d.ts +3 -0
- package/dist/modules/hash/hash.util.js +9 -0
- package/dist/modules/id/id.util.d.ts +7 -0
- package/dist/modules/id/id.util.js +33 -0
- package/dist/modules/injector/decorators/inject-token.decorator.d.ts +14 -0
- package/dist/modules/injector/decorators/inject-token.decorator.js +12 -0
- package/dist/modules/injector/decorators/injectable.decorator.d.ts +9 -0
- package/dist/modules/injector/decorators/injectable.decorator.js +7 -0
- package/dist/modules/injector/injector.model.d.ts +25 -0
- package/dist/modules/injector/injector.model.js +152 -0
- package/dist/modules/injector/provider-scopes.enum.d.ts +5 -0
- package/dist/modules/injector/provider-scopes.enum.js +6 -0
- package/dist/modules/injector/provider.interface.d.ts +10 -0
- package/dist/modules/injector/provider.interface.js +0 -0
- package/dist/modules/json-filter/json-filter.function.d.ts +41 -0
- package/dist/modules/json-filter/json-filter.function.js +75 -0
- package/dist/modules/logging/console-logger.model.d.ts +36 -0
- package/dist/modules/logging/console-logger.model.js +44 -0
- package/dist/modules/logging/logger.model.d.ts +6 -0
- package/dist/modules/logging/logger.model.js +7 -0
- package/dist/modules/logging/task.d.ts +38 -0
- package/dist/modules/logging/task.js +133 -0
- package/dist/modules/math/line.d.ts +12 -0
- package/dist/modules/math/line.js +50 -0
- package/dist/modules/math/point.d.ts +34 -0
- package/dist/modules/math/point.js +71 -0
- package/dist/modules/math/polygon.d.ts +45 -0
- package/dist/modules/math/polygon.js +273 -0
- package/dist/modules/math/rect.d.ts +6 -0
- package/dist/modules/math/rect.js +0 -0
- package/dist/modules/math/size.d.ts +4 -0
- package/dist/modules/math/size.js +0 -0
- package/dist/modules/number/number.util.d.ts +9 -0
- package/dist/modules/number/number.util.js +27 -0
- package/dist/modules/object/object.util.d.ts +7 -0
- package/dist/modules/object/object.util.js +63 -0
- package/dist/modules/path/path.util.d.ts +11 -0
- package/dist/modules/path/path.util.js +59 -0
- package/dist/modules/random/random.util.d.ts +17 -0
- package/dist/modules/random/random.util.js +57 -0
- package/dist/modules/readable-stream/readable-stream.util.d.ts +3 -0
- package/dist/modules/readable-stream/readable-stream.util.js +26 -0
- package/dist/modules/reflection/interfaces/parameter.interface.d.ts +4 -0
- package/dist/modules/reflection/interfaces/parameter.interface.js +0 -0
- package/dist/modules/reflection/models/attribute.model.d.ts +12 -0
- package/dist/modules/reflection/models/attribute.model.js +17 -0
- package/dist/modules/reflection/models/class-attribute.model.d.ts +4 -0
- package/dist/modules/reflection/models/class-attribute.model.js +6 -0
- package/dist/modules/reflection/models/method-attribute.model.d.ts +5 -0
- package/dist/modules/reflection/models/method-attribute.model.js +8 -0
- package/dist/modules/reflection/models/parameter-attribute.model.d.ts +7 -0
- package/dist/modules/reflection/models/parameter-attribute.model.js +21 -0
- package/dist/modules/reflection/models/property-attribute.model.d.ts +5 -0
- package/dist/modules/reflection/models/property-attribute.model.js +8 -0
- package/dist/modules/reflection/models/property-proxy-attribute.model.d.ts +15 -0
- package/dist/modules/reflection/models/property-proxy-attribute.model.js +19 -0
- package/dist/modules/reflection/types/constructor.type.d.ts +2 -0
- package/dist/modules/reflection/types/constructor.type.js +0 -0
- package/dist/modules/reflection/types/instance.type.d.ts +7 -0
- package/dist/modules/reflection/types/instance.type.js +0 -0
- package/dist/modules/reflection/types/type.type.d.ts +2 -0
- package/dist/modules/reflection/types/type.type.js +0 -0
- package/dist/modules/reflection/utils/decorator.util.d.ts +70 -0
- package/dist/modules/reflection/utils/decorator.util.js +135 -0
- package/dist/modules/reflection/utils/reflection.util.d.ts +140 -0
- package/dist/modules/reflection/utils/reflection.util.js +311 -0
- package/dist/modules/router/router.util.d.ts +33 -0
- package/dist/modules/router/router.util.js +59 -0
- package/dist/modules/state/adaptors/array/array-adaptor.util.d.ts +25 -0
- package/dist/modules/state/adaptors/array/array-adaptor.util.js +97 -0
- package/dist/modules/state/adaptors/entity/entity-adaptor.util.d.ts +35 -0
- package/dist/modules/state/adaptors/entity/entity-adaptor.util.js +158 -0
- package/dist/modules/state/adaptors/entity/entity-map.type.d.ts +4 -0
- package/dist/modules/state/adaptors/entity/entity-map.type.js +0 -0
- package/dist/modules/state/adaptors/entity/entity.interface.d.ts +3 -0
- package/dist/modules/state/adaptors/entity/entity.interface.js +0 -0
- package/dist/modules/state/state.model.d.ts +46 -0
- package/dist/modules/state/state.model.js +129 -0
- package/dist/modules/state/update.type.d.ts +2 -0
- package/dist/modules/state/update.type.js +0 -0
- package/dist/modules/string/string.util.d.ts +11 -0
- package/dist/modules/string/string.util.js +42 -0
- package/dist/modules/subscribable/subscribable.model.d.ts +10 -0
- package/dist/modules/subscribable/subscribable.model.js +34 -0
- package/dist/modules/subscribable/subscription.interface.d.ts +3 -0
- package/dist/modules/subscribable/subscription.interface.js +0 -0
- package/dist/modules/tson/error.d.ts +8 -0
- package/dist/modules/tson/error.js +13 -0
- package/dist/modules/tson/schema.d.ts +10 -0
- package/dist/modules/tson/schema.js +0 -0
- package/dist/modules/tson/schemas/any.d.ts +14 -0
- package/dist/modules/tson/schemas/any.js +27 -0
- package/dist/modules/tson/schemas/array.d.ts +21 -0
- package/dist/modules/tson/schemas/array.js +80 -0
- package/dist/modules/tson/schemas/boolean.d.ts +14 -0
- package/dist/modules/tson/schemas/boolean.js +38 -0
- package/dist/modules/tson/schemas/enum.d.ts +15 -0
- package/dist/modules/tson/schemas/enum.js +43 -0
- package/dist/modules/tson/schemas/number.d.ts +20 -0
- package/dist/modules/tson/schemas/number.js +66 -0
- package/dist/modules/tson/schemas/object.d.ts +33 -0
- package/dist/modules/tson/schemas/object.js +88 -0
- package/dist/modules/tson/schemas/schema-base.d.ts +12 -0
- package/dist/modules/tson/schemas/schema-base.js +14 -0
- package/dist/modules/tson/schemas/string.d.ts +19 -0
- package/dist/modules/tson/schemas/string.js +60 -0
- package/dist/modules/tson/schemas/union.d.ts +16 -0
- package/dist/modules/tson/schemas/union.js +56 -0
- package/dist/modules/tson/tson.d.ts +41 -0
- package/dist/modules/tson/tson.js +138 -0
- package/dist/modules/tson/type.d.ts +53 -0
- package/dist/modules/tson/type.js +0 -0
- package/dist/modules/value/value.util.d.ts +18 -0
- package/dist/modules/value/value.util.js +180 -0
- package/dist/types/awaitable.type.d.ts +1 -0
- package/dist/types/awaitable.type.js +0 -0
- package/dist/types/camel-to-kebab.type.d.ts +1 -0
- package/dist/types/camel-to-kebab.type.js +0 -0
- package/dist/types/has-key.type.d.ts +3 -0
- package/dist/types/has-key.type.js +0 -0
- package/dist/types/is-union.type.d.ts +1 -0
- package/dist/types/is-union.type.js +0 -0
- package/dist/types/keys-of-type.type.d.ts +5 -0
- package/dist/types/keys-of-type.type.js +0 -0
- package/dist/types/keys-with-fix.type.d.ts +3 -0
- package/dist/types/keys-with-fix.type.js +0 -0
- package/dist/types/optional-keys.type.d.ts +6 -0
- package/dist/types/optional-keys.type.js +0 -0
- package/dist/types/partial.type.d.ts +6 -0
- package/dist/types/partial.type.js +0 -0
- package/dist/types/predicate.type.d.ts +1 -0
- package/dist/types/predicate.type.js +0 -0
- package/dist/types/recursive-readonly.type.d.ts +3 -0
- package/dist/types/recursive-readonly.type.js +0 -0
- package/dist/types/recursive-value.type.d.ts +3 -0
- package/dist/types/recursive-value.type.js +0 -0
- package/dist/types/selector.type.d.ts +1 -0
- package/dist/types/selector.type.js +0 -0
- package/package.json +1 -1
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { parsePath } from '../../functions/parse-path-selector.function';
|
|
2
|
+
import { $Object } from '../object/object.util';
|
|
3
|
+
import { $Value } from '../value/value.util';
|
|
4
|
+
export class $Changes {
|
|
5
|
+
static deleted = '[deleted]';
|
|
6
|
+
static isArrayIndexChange(change) {
|
|
7
|
+
if (change == null || typeof change !== 'object' || Array.isArray(change))
|
|
8
|
+
return false;
|
|
9
|
+
if (!Object.keys(change).length)
|
|
10
|
+
return;
|
|
11
|
+
for (const k of Object.keys(change)) {
|
|
12
|
+
if (!k.startsWith('$'))
|
|
13
|
+
return false;
|
|
14
|
+
const key = k.endsWith('+') ? k.slice(1, -1) : k.slice(1);
|
|
15
|
+
const index = Number.parseInt(key, 10);
|
|
16
|
+
if (Number.isNaN(index))
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
static getArrayChanges(a, b) {
|
|
22
|
+
if ($Value.equals(a, b))
|
|
23
|
+
return;
|
|
24
|
+
const result = {};
|
|
25
|
+
let i = 0; // index in a
|
|
26
|
+
let j = 0; // index in b
|
|
27
|
+
while (i < a.length && j < b.length) {
|
|
28
|
+
if ($Value.equals(a[i], b[j])) {
|
|
29
|
+
i++;
|
|
30
|
+
j++;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
// Look for matches further ahead to detect multiple deletions/insertions
|
|
34
|
+
let foundDeletion = false;
|
|
35
|
+
for (let lookAhead = i + 1; lookAhead < a.length; lookAhead++) {
|
|
36
|
+
if ($Value.equals(a[lookAhead], b[j])) {
|
|
37
|
+
// Found a match - mark all items between as deleted
|
|
38
|
+
for (let k = i; k < lookAhead; k++) {
|
|
39
|
+
result[`$${k}`] = $Changes.deleted;
|
|
40
|
+
}
|
|
41
|
+
i = lookAhead;
|
|
42
|
+
foundDeletion = true;
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (foundDeletion)
|
|
47
|
+
continue;
|
|
48
|
+
// Look for insertions
|
|
49
|
+
let foundInsertion = false;
|
|
50
|
+
for (let lookAhead = j + 1; lookAhead < b.length; lookAhead++) {
|
|
51
|
+
if ($Value.equals(a[i], b[lookAhead])) {
|
|
52
|
+
// Found a match - mark all items between as insertions
|
|
53
|
+
for (let k = j; k < lookAhead; k++) {
|
|
54
|
+
result[`$${k}+`] = b[k];
|
|
55
|
+
}
|
|
56
|
+
j = lookAhead;
|
|
57
|
+
foundInsertion = true;
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (foundInsertion)
|
|
62
|
+
continue;
|
|
63
|
+
// Replace
|
|
64
|
+
result[`$${i}`] = $Changes.get(a[i], b[j]);
|
|
65
|
+
i++;
|
|
66
|
+
j++;
|
|
67
|
+
}
|
|
68
|
+
// Remaining items in a were deleted
|
|
69
|
+
for (; i < a.length; i++)
|
|
70
|
+
result[`$${i}`] = $Changes.deleted;
|
|
71
|
+
// Remaining items in b were appended (inserts at end)
|
|
72
|
+
for (; j < b.length; j++)
|
|
73
|
+
result[`$${j}+`] = b[j];
|
|
74
|
+
return Object.keys(result).length ? result : undefined;
|
|
75
|
+
}
|
|
76
|
+
static getObjectChanges(a, b) {
|
|
77
|
+
const changes = {};
|
|
78
|
+
const keys = new Set([...Object.keys(a), ...Object.keys(b)]);
|
|
79
|
+
for (const key of keys) {
|
|
80
|
+
if (!(key in b)) {
|
|
81
|
+
changes[key] = $Changes.deleted;
|
|
82
|
+
}
|
|
83
|
+
else if (!(key in a)) {
|
|
84
|
+
changes[key] = b[key];
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
const change = $Changes.get(a[key], b[key]);
|
|
88
|
+
if (change !== undefined) {
|
|
89
|
+
changes[key] = change;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return Object.keys(changes).length ? changes : undefined;
|
|
94
|
+
}
|
|
95
|
+
static get(a, b) {
|
|
96
|
+
if (a === b)
|
|
97
|
+
return;
|
|
98
|
+
if (a == null || b == null)
|
|
99
|
+
return b;
|
|
100
|
+
if (typeof a !== 'object')
|
|
101
|
+
return b;
|
|
102
|
+
if (typeof a !== typeof b)
|
|
103
|
+
return b;
|
|
104
|
+
if (Array.isArray(a) !== Array.isArray(b))
|
|
105
|
+
return b;
|
|
106
|
+
if (Array.isArray(a) && Array.isArray(b))
|
|
107
|
+
return $Changes.getArrayChanges(a, b);
|
|
108
|
+
return $Changes.getObjectChanges(a, b);
|
|
109
|
+
}
|
|
110
|
+
static classifyPathsByOverlap(changesA, changesB) {
|
|
111
|
+
const aPaths = $Object.getPaths(changesA);
|
|
112
|
+
const bPaths = $Object.getPaths(changesB);
|
|
113
|
+
const conflicts = new Set();
|
|
114
|
+
const differences = new Set();
|
|
115
|
+
for (const aPath of aPaths) {
|
|
116
|
+
if (bPaths.some(bPath => this.pathsOverlap(aPath, bPath)))
|
|
117
|
+
conflicts.add(aPath);
|
|
118
|
+
else
|
|
119
|
+
differences.add(aPath);
|
|
120
|
+
}
|
|
121
|
+
for (const bPath of bPaths) {
|
|
122
|
+
if (aPaths.some(aPath => this.pathsOverlap(aPath, bPath)))
|
|
123
|
+
conflicts.add(bPath);
|
|
124
|
+
else
|
|
125
|
+
differences.add(bPath);
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
conflicts: Array.from(conflicts),
|
|
129
|
+
differences: Array.from(differences)
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
static resolveConflicts(changesA, changesB) {
|
|
133
|
+
const { conflicts, differences } = this.classifyPathsByOverlap(changesA, changesB);
|
|
134
|
+
return {
|
|
135
|
+
differences: $Changes.excludeChanges(changesB, conflicts),
|
|
136
|
+
conflicts: $Changes.excludeChanges(changesB, differences)
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
static pathsOverlap(a, b) {
|
|
140
|
+
const selectorsA = parsePath(a);
|
|
141
|
+
const selectorsB = parsePath(b);
|
|
142
|
+
const length = Math.min(selectorsA.length, selectorsB.length);
|
|
143
|
+
for (let i = 0; i < length; i++) {
|
|
144
|
+
if (selectorsA[i] !== selectorsB[i])
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
static hasConflict(changesA, changesB) {
|
|
150
|
+
const aPaths = $Object.getPaths(changesA);
|
|
151
|
+
const bPaths = $Object.getPaths(changesB);
|
|
152
|
+
for (const bPath of bPaths) {
|
|
153
|
+
for (const aPath of aPaths) {
|
|
154
|
+
if (this.pathsOverlap(aPath, bPath))
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
static asValue(changes) {
|
|
161
|
+
if (changes === undefined)
|
|
162
|
+
return undefined;
|
|
163
|
+
if (Array.isArray(changes)) {
|
|
164
|
+
return changes.map(item => $Changes.asValue(item));
|
|
165
|
+
}
|
|
166
|
+
if (typeof changes === 'object' && changes !== null) {
|
|
167
|
+
// cannot materialize array index changes without a base; strip them
|
|
168
|
+
if ($Changes.isArrayIndexChange(changes))
|
|
169
|
+
return undefined;
|
|
170
|
+
const result = {};
|
|
171
|
+
for (const [key, value] of Object.entries(changes)) {
|
|
172
|
+
if (value === $Changes.deleted)
|
|
173
|
+
continue;
|
|
174
|
+
result[key] = $Changes.asValue(value);
|
|
175
|
+
}
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
return changes;
|
|
179
|
+
}
|
|
180
|
+
static apply(value, changes) {
|
|
181
|
+
function applyArrayChange(originalArray, change) {
|
|
182
|
+
if (!$Changes.isArrayIndexChange(change))
|
|
183
|
+
return $Value.clone(change);
|
|
184
|
+
const result = $Value.clone(originalArray);
|
|
185
|
+
const entries = Object.entries(change)
|
|
186
|
+
.map(([k, v]) => {
|
|
187
|
+
const isInsert = k.endsWith('+');
|
|
188
|
+
const nStr = isInsert ? k.slice(1, -1) : k.slice(1);
|
|
189
|
+
return [Number.parseInt(nStr, 10), isInsert, v];
|
|
190
|
+
})
|
|
191
|
+
.filter(([i]) => !Number.isNaN(i))
|
|
192
|
+
.sort(([iA, insA, vA], [iB, insB, vB]) => {
|
|
193
|
+
const aDel = vA === $Changes.deleted;
|
|
194
|
+
const bDel = vB === $Changes.deleted;
|
|
195
|
+
// deletes first, highest -> lowest
|
|
196
|
+
if (aDel !== bDel)
|
|
197
|
+
return aDel ? -1 : 1;
|
|
198
|
+
if (aDel && bDel)
|
|
199
|
+
return iB - iA;
|
|
200
|
+
// inserts next, lowest -> highest
|
|
201
|
+
if (insA !== insB)
|
|
202
|
+
return insA ? -1 : 1;
|
|
203
|
+
if (insA && insB)
|
|
204
|
+
return iA - iB;
|
|
205
|
+
// sets last, lowest -> highest
|
|
206
|
+
return iA - iB;
|
|
207
|
+
});
|
|
208
|
+
for (const [index, isInsert, op] of entries) {
|
|
209
|
+
if (op === $Changes.deleted) {
|
|
210
|
+
if (index >= 0 && index < result.length)
|
|
211
|
+
result.splice(index, 1);
|
|
212
|
+
}
|
|
213
|
+
else if (isInsert) {
|
|
214
|
+
const v = $Value.clone(op);
|
|
215
|
+
const idx = Math.min(Math.max(index, 0), result.length);
|
|
216
|
+
result.splice(idx, 0, v);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
if (index >= result.length)
|
|
220
|
+
result.length = index + 1;
|
|
221
|
+
result[index] = $Changes.apply(result[index], op);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return result;
|
|
225
|
+
}
|
|
226
|
+
if (changes === undefined)
|
|
227
|
+
return value;
|
|
228
|
+
if (value == null || typeof changes !== 'object')
|
|
229
|
+
return $Changes.asValue(changes);
|
|
230
|
+
if (Array.isArray(value)) {
|
|
231
|
+
return applyArrayChange(value, changes);
|
|
232
|
+
}
|
|
233
|
+
else if (typeof value === 'object') {
|
|
234
|
+
if (Array.isArray(changes))
|
|
235
|
+
return $Changes.asValue(changes);
|
|
236
|
+
const result = { ...value };
|
|
237
|
+
for (const [key, change] of Object.entries(changes)) {
|
|
238
|
+
if (change === $Changes.deleted) {
|
|
239
|
+
delete result[key];
|
|
240
|
+
}
|
|
241
|
+
else if (Array.isArray(result[key])) {
|
|
242
|
+
result[key] = applyArrayChange(result[key] || [], change);
|
|
243
|
+
}
|
|
244
|
+
else if (typeof change === 'object' && change !== null) {
|
|
245
|
+
result[key] = $Changes.apply(result[key], change);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
result[key] = change;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return result;
|
|
252
|
+
}
|
|
253
|
+
return $Changes.asValue(changes);
|
|
254
|
+
}
|
|
255
|
+
static rebase(source, local, remote) {
|
|
256
|
+
const localChanges = $Changes.get(source, local);
|
|
257
|
+
const remoteChanges = $Changes.get(source, remote);
|
|
258
|
+
if (localChanges === undefined || $Value.equals(localChanges, remoteChanges)) {
|
|
259
|
+
return { result: $Changes.apply(source, remoteChanges) };
|
|
260
|
+
}
|
|
261
|
+
if (remoteChanges === undefined) {
|
|
262
|
+
return { result: $Changes.apply(source, localChanges) };
|
|
263
|
+
}
|
|
264
|
+
else if (!$Changes.hasConflict(remoteChanges, localChanges)) {
|
|
265
|
+
let result = $Changes.apply(source, localChanges);
|
|
266
|
+
result = $Changes.apply(result, remoteChanges);
|
|
267
|
+
return { result };
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
const localConflict = $Changes.resolveConflicts(remoteChanges, localChanges);
|
|
271
|
+
const remoteConflict = $Changes.resolveConflicts(localChanges, remoteChanges);
|
|
272
|
+
const sourceWithDifferences = $Changes.apply($Changes.apply(source, remoteConflict.differences), localConflict.differences);
|
|
273
|
+
const mergedWithLocalDifferences = $Changes.apply(remote, localConflict.differences);
|
|
274
|
+
return {
|
|
275
|
+
conflicts: {
|
|
276
|
+
local: localConflict,
|
|
277
|
+
remote: remoteConflict,
|
|
278
|
+
},
|
|
279
|
+
merge: {
|
|
280
|
+
source: sourceWithDifferences,
|
|
281
|
+
remote: $Changes.apply(sourceWithDifferences, remoteConflict.conflicts),
|
|
282
|
+
local: $Changes.apply(sourceWithDifferences, localConflict.conflicts),
|
|
283
|
+
result: mergedWithLocalDifferences
|
|
284
|
+
},
|
|
285
|
+
result: $Changes.apply(mergedWithLocalDifferences, localConflict.conflicts)
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Excludes specific paths from a changes object and cleans up empty containers.
|
|
291
|
+
* Empty objects {} left behind after exclusion are recursively cleaned up,
|
|
292
|
+
* unless they existed in the original changes (intentional {} changes are preserved).
|
|
293
|
+
*
|
|
294
|
+
* @param changes - The changes object to filter
|
|
295
|
+
* @param paths - Array of dot-notation paths to exclude (e.g., ['user.name', 'config.theme'])
|
|
296
|
+
* @returns The filtered changes object with empty containers cleaned up
|
|
297
|
+
*/
|
|
298
|
+
static excludeChanges(changes, paths) {
|
|
299
|
+
if (!paths.length)
|
|
300
|
+
return changes;
|
|
301
|
+
if (typeof changes !== 'object' || changes == null || Array.isArray(changes))
|
|
302
|
+
return changes;
|
|
303
|
+
const result = $Value.clone(changes);
|
|
304
|
+
for (const pathString of paths) {
|
|
305
|
+
$Value.unset(result, pathString);
|
|
306
|
+
}
|
|
307
|
+
function cleanupEmptyObjects(current, original) {
|
|
308
|
+
if (current == null || typeof current !== 'object')
|
|
309
|
+
return current;
|
|
310
|
+
if (Array.isArray(current))
|
|
311
|
+
return current.map((item, index) => cleanupEmptyObjects(item, original?.[index]));
|
|
312
|
+
const cleaned = {};
|
|
313
|
+
for (const [key, value] of Object.entries(current)) {
|
|
314
|
+
if (value === $Changes.deleted) {
|
|
315
|
+
cleaned[key] = value;
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
const cleanedValue = cleanupEmptyObjects(value, original?.[key]);
|
|
319
|
+
if (cleanedValue === undefined)
|
|
320
|
+
continue;
|
|
321
|
+
if (!$Object.isEmptyObject(cleanedValue) || $Object.isEmptyObject(original?.[key]))
|
|
322
|
+
cleaned[key] = cleanedValue;
|
|
323
|
+
}
|
|
324
|
+
if (Object.keys(cleaned).length === 0)
|
|
325
|
+
return $Object.isEmptyObject(original) ? {} : undefined;
|
|
326
|
+
return cleaned;
|
|
327
|
+
}
|
|
328
|
+
return cleanupEmptyObjects(result, changes);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Color } from './color.type';
|
|
2
|
+
import type { ColorData } from './color-data.interface';
|
|
3
|
+
import { ColorFormats } from './color-formats.const';
|
|
4
|
+
import type { HSL } from './hsl.interface';
|
|
5
|
+
import type { HSV } from './hsv.interface';
|
|
6
|
+
import type { RGB } from './rgb.interface';
|
|
7
|
+
export declare class $Color {
|
|
8
|
+
private constructor();
|
|
9
|
+
static random(format: '#'): string;
|
|
10
|
+
static random(format: '0x'): number;
|
|
11
|
+
static from(value?: Color): ColorData;
|
|
12
|
+
static equal(target: Color, value: Color): boolean;
|
|
13
|
+
static isRgb(value: Color): boolean;
|
|
14
|
+
static isHsl(value: Color): boolean;
|
|
15
|
+
static isHsv(value: Color): boolean;
|
|
16
|
+
static isHex(value: Color): boolean;
|
|
17
|
+
static convertHexToHex0(hex: string): number;
|
|
18
|
+
static convertHex0ToHex(hex: number): string;
|
|
19
|
+
static convertHexToRgb(hex: string): RGB;
|
|
20
|
+
static convertRgbToCss(rgb: RGB): string;
|
|
21
|
+
static convertHslToCss(hsl: HSL): string;
|
|
22
|
+
static convertRgbToHsl(rgb: RGB): HSL;
|
|
23
|
+
static convertHslToRgb(hsl: HSL): RGB;
|
|
24
|
+
static convertHslToHsv(hsl: HSL): HSV;
|
|
25
|
+
static convertHsvToHsl(hsv: HSV): HSL;
|
|
26
|
+
static convertHexToHsv(hex: string): HSV;
|
|
27
|
+
static convertHslToHex(hsl: HSL, type?: '#'): string;
|
|
28
|
+
static convertHslToHex(hsl: HSL, type?: '0x'): number;
|
|
29
|
+
static convertHexToHsl(hex: string): HSL;
|
|
30
|
+
static convertHsvToRgb(hsv: HSV): RGB;
|
|
31
|
+
static convertHsvToHex(hsv: HSV, type?: '#'): string;
|
|
32
|
+
static convertHsvToHex(hsv: HSV, type?: '0x'): number;
|
|
33
|
+
static convertRgbToHex(rgb: RGB, type?: '#'): string;
|
|
34
|
+
static convertRgbToHex(rgb: RGB, type?: '0x'): number;
|
|
35
|
+
static convertRgbToHsv(rgb: RGB): HSV;
|
|
36
|
+
static convertHexToName(hex: string): string;
|
|
37
|
+
static convertNameToHex(name: string, type?: '#'): string;
|
|
38
|
+
static convertNameToHex(name: string, type?: '0x'): number;
|
|
39
|
+
static getFormat(color: string | number): ColorFormats;
|
|
40
|
+
static parse(color: string | number): ColorData;
|
|
41
|
+
}
|