@oscarpalmer/atoms 0.191.0 → 0.192.0
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/beacon.d.mts +6 -44
- package/dist/beacon.mjs +20 -67
- package/dist/color/constants.d.mts +82 -41
- package/dist/color/constants.mjs +102 -63
- package/dist/color/instance.mjs +36 -13
- package/dist/color/misc/alpha.mjs +9 -10
- package/dist/color/misc/format.mjs +4 -4
- package/dist/color/misc/get.mjs +18 -18
- package/dist/color/misc/is.mjs +22 -21
- package/dist/color/misc/state.d.mts +6 -5
- package/dist/color/misc/state.mjs +31 -26
- package/dist/color/models.d.mts +78 -1
- package/dist/color/space/hex.mjs +12 -12
- package/dist/color/space/hsl.mjs +16 -16
- package/dist/color/space/hwb.mjs +10 -10
- package/dist/color/space/rgb.mjs +16 -16
- package/dist/herald.d.mts +2 -3
- package/dist/index.d.mts +117 -45
- package/dist/index.mjs +522 -360
- package/dist/internal/subscription.d.mts +52 -0
- package/dist/internal/subscription.mjs +127 -0
- package/dist/models.d.mts +5 -1
- package/package.json +1 -1
- package/src/beacon.ts +32 -117
- package/src/color/constants.ts +115 -78
- package/src/color/instance.ts +65 -12
- package/src/color/misc/alpha.ts +13 -21
- package/src/color/misc/format.ts +4 -4
- package/src/color/misc/get.ts +23 -40
- package/src/color/misc/is.ts +29 -39
- package/src/color/misc/state.ts +77 -41
- package/src/color/models.ts +94 -1
- package/src/color/space/hex.ts +18 -23
- package/src/color/space/hsl.ts +16 -24
- package/src/color/space/hwb.ts +10 -10
- package/src/color/space/rgb.ts +19 -16
- package/src/herald.ts +1 -3
- package/src/index.ts +1 -0
- package/src/internal/subscription.ts +264 -0
- package/src/models.ts +5 -0
- package/src/string/fuzzy.ts +1 -1
- package/src/value/freeze.ts +2 -2
- package/src/value/shake.ts +1 -1
- package/src/value/transform.ts +1 -1
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import type {Key} from '../models';
|
|
2
|
+
import {isPlainObject} from './is';
|
|
3
|
+
|
|
4
|
+
// #region Types
|
|
5
|
+
|
|
6
|
+
export type Subscription = {
|
|
7
|
+
/**
|
|
8
|
+
* Is the subscription active?
|
|
9
|
+
*/
|
|
10
|
+
get active(): boolean;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Unsubscribe from changes
|
|
14
|
+
*/
|
|
15
|
+
unsubscribe(): void;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type SubscriptionParameters = {
|
|
19
|
+
isActive?: () => boolean;
|
|
20
|
+
key?: Key;
|
|
21
|
+
property: SubscriptionProperty;
|
|
22
|
+
subscriptions: Subscriptions;
|
|
23
|
+
value: unknown;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export type SubscriptionProperty = {
|
|
27
|
+
key: string;
|
|
28
|
+
value: unknown;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
type SubscriptionState = {
|
|
32
|
+
active: boolean;
|
|
33
|
+
parameters: SubscriptionParameters;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type Subscriptions<Value = unknown> = {
|
|
37
|
+
items: SubscriptionsItems;
|
|
38
|
+
keys?: Set<Key>;
|
|
39
|
+
values: SubscriptionsValues<Value>;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
type SubscriptionsItems = {
|
|
43
|
+
any: Set<Subscription>;
|
|
44
|
+
keyed?: Map<Key, Set<Subscription>>;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
type SubscriptionsValues<Value = unknown> = {
|
|
48
|
+
from: SubscriptionsValuesItem<Value, Subscription>;
|
|
49
|
+
to: SubscriptionsValuesItem<Subscription, Value>;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
type SubscriptionsValuesItem<MapKey, MapValue> = {
|
|
53
|
+
any: Map<MapKey, MapValue>;
|
|
54
|
+
keyed?: Map<Key, Map<MapKey, MapValue>>;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// #endregion
|
|
58
|
+
|
|
59
|
+
// #region Functions
|
|
60
|
+
|
|
61
|
+
function addSubscription(subscription: Subscription, state: SubscriptionState): void {
|
|
62
|
+
const {key, subscriptions, value} = state.parameters;
|
|
63
|
+
const {items, values} = subscriptions;
|
|
64
|
+
|
|
65
|
+
if (key == null) {
|
|
66
|
+
items.any.add(subscription);
|
|
67
|
+
values.from.any.set(value, subscription);
|
|
68
|
+
values.to.any.set(subscription, value);
|
|
69
|
+
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (items.keyed == null || values.from.keyed == null || values.to.keyed == null) {
|
|
74
|
+
// TODO: fix tests or document
|
|
75
|
+
// istanbul ignore next
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
let keyedItems = items.keyed.get(key);
|
|
80
|
+
|
|
81
|
+
if (keyedItems == null) {
|
|
82
|
+
keyedItems = new Set();
|
|
83
|
+
|
|
84
|
+
items.keyed.set(key, keyedItems);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
keyedItems.add(subscription);
|
|
88
|
+
|
|
89
|
+
let keyedFrom = values.from.keyed.get(key);
|
|
90
|
+
|
|
91
|
+
if (keyedFrom == null) {
|
|
92
|
+
keyedFrom = new Map();
|
|
93
|
+
|
|
94
|
+
values.from.keyed.set(key, keyedFrom);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
keyedFrom.set(value, subscription);
|
|
98
|
+
|
|
99
|
+
let keyedTo = values.to.keyed.get(key);
|
|
100
|
+
|
|
101
|
+
if (keyedTo == null) {
|
|
102
|
+
keyedTo = new Map();
|
|
103
|
+
|
|
104
|
+
values.to.keyed.set(key, keyedTo);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
keyedTo.set(subscription, value);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function clearSubscriptions(store: Subscriptions): void {
|
|
111
|
+
for (const susbcription of store.values.to.any.keys()) {
|
|
112
|
+
susbcription.unsubscribe();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (store.values.to.keyed != null) {
|
|
116
|
+
for (const values of store.values.to.keyed.values()) {
|
|
117
|
+
for (const susbcription of values.keys()) {
|
|
118
|
+
susbcription.unsubscribe();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function getExistingSubscription(state: SubscriptionState): Subscription | undefined {
|
|
125
|
+
const {parameters} = state;
|
|
126
|
+
const {values} = parameters.subscriptions;
|
|
127
|
+
|
|
128
|
+
return parameters.key == null
|
|
129
|
+
? values.from.any.get(parameters.value)
|
|
130
|
+
: values.from.keyed?.get(parameters.key)?.get(parameters.value);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function getSubscription(parameters: SubscriptionParameters): Subscription {
|
|
134
|
+
const state: SubscriptionState = {
|
|
135
|
+
parameters,
|
|
136
|
+
active: true,
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const existing = getExistingSubscription(state);
|
|
140
|
+
|
|
141
|
+
if (existing != null) {
|
|
142
|
+
return existing;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (
|
|
146
|
+
parameters.subscriptions.keys != null &&
|
|
147
|
+
parameters.key != null &&
|
|
148
|
+
!parameters.subscriptions.keys.has(parameters.key)
|
|
149
|
+
) {
|
|
150
|
+
throw new Error();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const instance = {
|
|
154
|
+
unsubscribe: () => {
|
|
155
|
+
removeSubscription(instance as Subscription, state);
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
Object.defineProperties(instance, {
|
|
160
|
+
[PROPERTY]: {
|
|
161
|
+
enumerable: false,
|
|
162
|
+
value: true,
|
|
163
|
+
},
|
|
164
|
+
[parameters.property.key]: {
|
|
165
|
+
enumerable: false,
|
|
166
|
+
value: parameters.property.value,
|
|
167
|
+
},
|
|
168
|
+
active: {
|
|
169
|
+
enumerable: true,
|
|
170
|
+
get: () => (parameters.isActive?.() ?? true) && state.active,
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
addSubscription(instance as Subscription, state);
|
|
175
|
+
|
|
176
|
+
return Object.freeze(instance) as Subscription;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export function getSubscriptions<Value = unknown>(keys?: Set<Key>): Subscriptions<Value> {
|
|
180
|
+
return {
|
|
181
|
+
keys,
|
|
182
|
+
items: {
|
|
183
|
+
any: new Set(),
|
|
184
|
+
keyed: keys == null ? undefined : new Map(),
|
|
185
|
+
},
|
|
186
|
+
values: {
|
|
187
|
+
from: {
|
|
188
|
+
any: new Map(),
|
|
189
|
+
keyed: keys == null ? undefined : new Map(),
|
|
190
|
+
},
|
|
191
|
+
to: {
|
|
192
|
+
any: new Map(),
|
|
193
|
+
keyed: keys == null ? undefined : new Map(),
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Is the value a subscription?
|
|
201
|
+
*
|
|
202
|
+
* @param value Value to check
|
|
203
|
+
* @returns `true` if the value is a subscription, otherwise `false`
|
|
204
|
+
*/
|
|
205
|
+
export function isSubscription(value: unknown): value is Subscription {
|
|
206
|
+
return isPlainObject(value) && PROPERTY in value && value[PROPERTY] === true;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function removeFromStore(
|
|
210
|
+
items: Set<Subscription>,
|
|
211
|
+
values: SubscriptionsValues,
|
|
212
|
+
subscription: Subscription,
|
|
213
|
+
value: unknown,
|
|
214
|
+
key?: Key,
|
|
215
|
+
): void {
|
|
216
|
+
items.delete(subscription);
|
|
217
|
+
|
|
218
|
+
if (key == null) {
|
|
219
|
+
values.from.any.delete(value);
|
|
220
|
+
values.to.any.delete(subscription);
|
|
221
|
+
} else {
|
|
222
|
+
values.from.keyed?.get(key)?.delete(value);
|
|
223
|
+
values.to.keyed?.get(key)?.delete(subscription);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function removeSubscription(subscription: Subscription, state: SubscriptionState): void {
|
|
228
|
+
if (!state.active) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
state.active = false;
|
|
233
|
+
|
|
234
|
+
const {key, subscriptions, value} = state.parameters;
|
|
235
|
+
const {items, values} = subscriptions;
|
|
236
|
+
|
|
237
|
+
if (key == null) {
|
|
238
|
+
removeFromStore(items.any, values, subscription, value);
|
|
239
|
+
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const keyed = items.keyed?.get(key);
|
|
244
|
+
|
|
245
|
+
if (items.keyed == null || keyed == null) {
|
|
246
|
+
// TODO, fix tests or document
|
|
247
|
+
// istanbul ignore next
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
removeFromStore(keyed, values, subscription, value, key);
|
|
252
|
+
|
|
253
|
+
if (keyed.size === 0) {
|
|
254
|
+
items.keyed.delete(key);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// #endregion
|
|
259
|
+
|
|
260
|
+
// #region Variables
|
|
261
|
+
|
|
262
|
+
const PROPERTY = '$subscription';
|
|
263
|
+
|
|
264
|
+
// #endregion
|
package/src/models.ts
CHANGED
package/src/string/fuzzy.ts
CHANGED
package/src/value/freeze.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {noop} from '../function';
|
|
2
|
-
import {isPlainObject} from '../is';
|
|
3
|
-
import type {
|
|
2
|
+
import {isPlainObject} from '../internal/is';
|
|
3
|
+
import type {PlainObject} from '../models';
|
|
4
4
|
|
|
5
5
|
// #region Types
|
|
6
6
|
|
package/src/value/shake.ts
CHANGED
package/src/value/transform.ts
CHANGED