@oscarpalmer/atoms 0.190.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.
Files changed (57) hide show
  1. package/dist/beacon.d.mts +6 -44
  2. package/dist/beacon.mjs +20 -67
  3. package/dist/color/constants.d.mts +82 -35
  4. package/dist/color/constants.mjs +106 -61
  5. package/dist/color/index.d.mts +3 -3
  6. package/dist/color/index.mjs +2 -2
  7. package/dist/color/instance.mjs +60 -35
  8. package/dist/color/misc/alpha.d.mts +1 -1
  9. package/dist/color/misc/alpha.mjs +12 -10
  10. package/dist/color/misc/format.d.mts +7 -0
  11. package/dist/color/misc/format.mjs +20 -0
  12. package/dist/color/misc/get.mjs +25 -25
  13. package/dist/color/misc/is.d.mts +0 -36
  14. package/dist/color/misc/is.mjs +22 -57
  15. package/dist/color/misc/state.d.mts +8 -6
  16. package/dist/color/misc/state.mjs +79 -88
  17. package/dist/color/models.d.mts +106 -6
  18. package/dist/color/space/hex.d.mts +3 -2
  19. package/dist/color/space/hex.mjs +22 -10
  20. package/dist/color/space/hsl.d.mts +3 -2
  21. package/dist/color/space/hsl.mjs +26 -14
  22. package/dist/color/space/hwb.d.mts +3 -2
  23. package/dist/color/space/hwb.mjs +20 -8
  24. package/dist/color/space/rgb.d.mts +3 -2
  25. package/dist/color/space/rgb.mjs +27 -15
  26. package/dist/herald.d.mts +2 -3
  27. package/dist/index.d.mts +139 -73
  28. package/dist/index.mjs +653 -477
  29. package/dist/internal/subscription.d.mts +52 -0
  30. package/dist/internal/subscription.mjs +127 -0
  31. package/dist/models.d.mts +5 -1
  32. package/package.json +4 -4
  33. package/src/beacon.ts +32 -117
  34. package/src/color/constants.ts +115 -66
  35. package/src/color/index.ts +26 -8
  36. package/src/color/instance.ts +113 -45
  37. package/src/color/misc/alpha.ts +18 -20
  38. package/src/color/misc/format.ts +29 -0
  39. package/src/color/misc/get.ts +31 -41
  40. package/src/color/misc/is.ts +31 -71
  41. package/src/color/misc/state.ts +165 -141
  42. package/src/color/models.ts +126 -5
  43. package/src/color/space/hex.ts +46 -18
  44. package/src/color/space/hsl.ts +44 -14
  45. package/src/color/space/hwb.ts +38 -8
  46. package/src/color/space/rgb.ts +48 -15
  47. package/src/herald.ts +1 -3
  48. package/src/index.ts +1 -0
  49. package/src/internal/subscription.ts +264 -0
  50. package/src/models.ts +5 -0
  51. package/src/string/fuzzy.ts +1 -1
  52. package/src/value/freeze.ts +2 -2
  53. package/src/value/shake.ts +1 -1
  54. package/src/value/transform.ts +1 -1
  55. package/dist/color/misc/index.d.mts +0 -7
  56. package/dist/color/misc/index.mjs +0 -15
  57. package/src/color/misc/index.ts +0 -29
@@ -0,0 +1,52 @@
1
+ import { Key } from "../models.mjs";
2
+ //#region src/internal/subscription.d.ts
3
+ type Subscription = {
4
+ /**
5
+ * Is the subscription active?
6
+ */
7
+ get active(): boolean;
8
+ /**
9
+ * Unsubscribe from changes
10
+ */
11
+ unsubscribe(): void;
12
+ };
13
+ type SubscriptionParameters = {
14
+ isActive?: () => boolean;
15
+ key?: Key;
16
+ property: SubscriptionProperty;
17
+ subscriptions: Subscriptions;
18
+ value: unknown;
19
+ };
20
+ type SubscriptionProperty = {
21
+ key: string;
22
+ value: unknown;
23
+ };
24
+ type Subscriptions<Value = unknown> = {
25
+ items: SubscriptionsItems;
26
+ keys?: Set<Key>;
27
+ values: SubscriptionsValues<Value>;
28
+ };
29
+ type SubscriptionsItems = {
30
+ any: Set<Subscription>;
31
+ keyed?: Map<Key, Set<Subscription>>;
32
+ };
33
+ type SubscriptionsValues<Value = unknown> = {
34
+ from: SubscriptionsValuesItem<Value, Subscription>;
35
+ to: SubscriptionsValuesItem<Subscription, Value>;
36
+ };
37
+ type SubscriptionsValuesItem<MapKey, MapValue> = {
38
+ any: Map<MapKey, MapValue>;
39
+ keyed?: Map<Key, Map<MapKey, MapValue>>;
40
+ };
41
+ declare function clearSubscriptions(store: Subscriptions): void;
42
+ declare function getSubscription(parameters: SubscriptionParameters): Subscription;
43
+ declare function getSubscriptions<Value = unknown>(keys?: Set<Key>): Subscriptions<Value>;
44
+ /**
45
+ * Is the value a subscription?
46
+ *
47
+ * @param value Value to check
48
+ * @returns `true` if the value is a subscription, otherwise `false`
49
+ */
50
+ declare function isSubscription(value: unknown): value is Subscription;
51
+ //#endregion
52
+ export { Subscription, SubscriptionParameters, SubscriptionProperty, Subscriptions, clearSubscriptions, getSubscription, getSubscriptions, isSubscription };
@@ -0,0 +1,127 @@
1
+ import { isPlainObject } from "./is.mjs";
2
+ //#region src/internal/subscription.ts
3
+ function addSubscription(subscription, state) {
4
+ const { key, subscriptions, value } = state.parameters;
5
+ const { items, values } = subscriptions;
6
+ if (key == null) {
7
+ items.any.add(subscription);
8
+ values.from.any.set(value, subscription);
9
+ values.to.any.set(subscription, value);
10
+ return;
11
+ }
12
+ if (items.keyed == null || values.from.keyed == null || values.to.keyed == null)
13
+ // istanbul ignore next
14
+ return;
15
+ let keyedItems = items.keyed.get(key);
16
+ if (keyedItems == null) {
17
+ keyedItems = /* @__PURE__ */ new Set();
18
+ items.keyed.set(key, keyedItems);
19
+ }
20
+ keyedItems.add(subscription);
21
+ let keyedFrom = values.from.keyed.get(key);
22
+ if (keyedFrom == null) {
23
+ keyedFrom = /* @__PURE__ */ new Map();
24
+ values.from.keyed.set(key, keyedFrom);
25
+ }
26
+ keyedFrom.set(value, subscription);
27
+ let keyedTo = values.to.keyed.get(key);
28
+ if (keyedTo == null) {
29
+ keyedTo = /* @__PURE__ */ new Map();
30
+ values.to.keyed.set(key, keyedTo);
31
+ }
32
+ keyedTo.set(subscription, value);
33
+ }
34
+ function clearSubscriptions(store) {
35
+ for (const susbcription of store.values.to.any.keys()) susbcription.unsubscribe();
36
+ if (store.values.to.keyed != null) for (const values of store.values.to.keyed.values()) for (const susbcription of values.keys()) susbcription.unsubscribe();
37
+ }
38
+ function getExistingSubscription(state) {
39
+ const { parameters } = state;
40
+ const { values } = parameters.subscriptions;
41
+ return parameters.key == null ? values.from.any.get(parameters.value) : values.from.keyed?.get(parameters.key)?.get(parameters.value);
42
+ }
43
+ function getSubscription(parameters) {
44
+ const state = {
45
+ parameters,
46
+ active: true
47
+ };
48
+ const existing = getExistingSubscription(state);
49
+ if (existing != null) return existing;
50
+ if (parameters.subscriptions.keys != null && parameters.key != null && !parameters.subscriptions.keys.has(parameters.key)) throw new Error();
51
+ const instance = { unsubscribe: () => {
52
+ removeSubscription(instance, state);
53
+ } };
54
+ Object.defineProperties(instance, {
55
+ [PROPERTY]: {
56
+ enumerable: false,
57
+ value: true
58
+ },
59
+ [parameters.property.key]: {
60
+ enumerable: false,
61
+ value: parameters.property.value
62
+ },
63
+ active: {
64
+ enumerable: true,
65
+ get: () => (parameters.isActive?.() ?? true) && state.active
66
+ }
67
+ });
68
+ addSubscription(instance, state);
69
+ return Object.freeze(instance);
70
+ }
71
+ function getSubscriptions(keys) {
72
+ return {
73
+ keys,
74
+ items: {
75
+ any: /* @__PURE__ */ new Set(),
76
+ keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
77
+ },
78
+ values: {
79
+ from: {
80
+ any: /* @__PURE__ */ new Map(),
81
+ keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
82
+ },
83
+ to: {
84
+ any: /* @__PURE__ */ new Map(),
85
+ keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
86
+ }
87
+ }
88
+ };
89
+ }
90
+ /**
91
+ * Is the value a subscription?
92
+ *
93
+ * @param value Value to check
94
+ * @returns `true` if the value is a subscription, otherwise `false`
95
+ */
96
+ function isSubscription(value) {
97
+ return isPlainObject(value) && PROPERTY in value && value[PROPERTY] === true;
98
+ }
99
+ function removeFromStore(items, values, subscription, value, key) {
100
+ items.delete(subscription);
101
+ if (key == null) {
102
+ values.from.any.delete(value);
103
+ values.to.any.delete(subscription);
104
+ } else {
105
+ values.from.keyed?.get(key)?.delete(value);
106
+ values.to.keyed?.get(key)?.delete(subscription);
107
+ }
108
+ }
109
+ function removeSubscription(subscription, state) {
110
+ if (!state.active) return;
111
+ state.active = false;
112
+ const { key, subscriptions, value } = state.parameters;
113
+ const { items, values } = subscriptions;
114
+ if (key == null) {
115
+ removeFromStore(items.any, values, subscription, value);
116
+ return;
117
+ }
118
+ const keyed = items.keyed?.get(key);
119
+ if (items.keyed == null || keyed == null)
120
+ // istanbul ignore next
121
+ return;
122
+ removeFromStore(keyed, values, subscription, value, key);
123
+ if (keyed.size === 0) items.keyed.delete(key);
124
+ }
125
+ const PROPERTY = "$subscription";
126
+ //#endregion
127
+ export { clearSubscriptions, getSubscription, getSubscriptions, isSubscription };
package/dist/models.d.mts CHANGED
@@ -156,5 +156,9 @@ type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint
156
156
  * Thanks, type-fest!
157
157
  */
158
158
  type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends ((mergedIntersection: infer Intersection) => void) ? Intersection & Union : never;
159
+ /**
160
+ * A function that unsubscribes from a subscription
161
+ */
162
+ type Unsubscriber = () => void;
159
163
  //#endregion
160
- export { ArrayOrPlainObject, AsyncCancelableCallback, BuiltIns, CancelableCallback, Constructor, EventPosition, GenericAsyncCallback, GenericCallback, Key, KeyedValue, NestedArray, NestedKeys, NestedPartial, NestedValue, NestedValues, NumericalKeys, NumericalValues, OnceAsyncCallback, OnceCallback, PlainObject, Primitive, RequiredKeys, Simplify, ToString, TypedArray, UnionToIntersection };
164
+ export { ArrayOrPlainObject, AsyncCancelableCallback, BuiltIns, CancelableCallback, Constructor, EventPosition, GenericAsyncCallback, GenericCallback, Key, KeyedValue, NestedArray, NestedKeys, NestedPartial, NestedValue, NestedValues, NumericalKeys, NumericalValues, OnceAsyncCallback, OnceCallback, PlainObject, Primitive, RequiredKeys, Simplify, ToString, TypedArray, UnionToIntersection, Unsubscriber };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscarpalmer/atoms",
3
- "version": "0.190.0",
3
+ "version": "0.192.0",
4
4
  "description": "Atomic utilities for making your JavaScript better.",
5
5
  "keywords": [
6
6
  "helper",
@@ -257,10 +257,10 @@
257
257
  "watch": "npx vite build --watch"
258
258
  },
259
259
  "devDependencies": {
260
- "@oxlint/plugins": "^1.78",
260
+ "@oxlint/plugins": "^1.79",
261
261
  "@types/node": "^26.2",
262
- "@vitest/coverage-istanbul": "4.1.10",
263
- "eslint": "^10.8",
262
+ "@vitest/coverage-istanbul": "^4.1",
263
+ "eslint": "^10.9",
264
264
  "jsdom": "^30",
265
265
  "tsdown": "^0.22",
266
266
  "typescript": "^6",
package/src/beacon.ts CHANGED
@@ -1,5 +1,13 @@
1
1
  import {noop} from './internal/function/misc';
2
2
  import {isPlainObject} from './internal/is';
3
+ import {
4
+ clearSubscriptions,
5
+ getSubscription,
6
+ getSubscriptions,
7
+ type Subscription,
8
+ type SubscriptionProperty,
9
+ type Subscriptions,
10
+ } from './internal/subscription';
3
11
  import type {PlainObject} from './models';
4
12
 
5
13
  // #region Types
@@ -13,11 +21,6 @@ export type Beacon<Value> = {
13
21
  */
14
22
  get active(): boolean;
15
23
 
16
- /**
17
- * Is the beacon closed?
18
- */
19
- get closed(): boolean;
20
-
21
24
  /**
22
25
  * The observable that can be subscribed to
23
26
  */
@@ -29,9 +32,9 @@ export type Beacon<Value> = {
29
32
  get value(): Value;
30
33
 
31
34
  /**
32
- * Close the beacon
35
+ * Deactivate the beacon
33
36
  */
34
- close(): void;
37
+ deactivate(): void;
35
38
 
36
39
  /**
37
40
  * Emit a new value
@@ -55,9 +58,6 @@ export type Beacon<Value> = {
55
58
  finish(): void;
56
59
  };
57
60
 
58
- /**
59
- * Options for Beacon
60
- */
61
61
  export type BeaconOptions<Value> = {
62
62
  /**
63
63
  * Method for comparing values for equality
@@ -73,8 +73,8 @@ export type BeaconOptions<Value> = {
73
73
  type BeaconState<Value> = {
74
74
  active: boolean;
75
75
  observable: Observable<Value>;
76
- observers: Map<Subscription, Observer<Value>>;
77
76
  options: Required<BeaconOptions<Value>>;
77
+ subscriptions: Subscriptions<Observer<unknown>>;
78
78
  value: Value;
79
79
  };
80
80
 
@@ -85,14 +85,9 @@ export type Observable<Value> = {
85
85
  get active(): boolean;
86
86
 
87
87
  /**
88
- * Is the observable closed?
89
- */
90
- get closed(): boolean;
91
-
92
- /**
93
- * Close the observable
88
+ * Deactivate the observable
94
89
  */
95
- close(): void;
90
+ deactivate(): void;
96
91
 
97
92
  /**
98
93
  * Subscribe to value changes
@@ -122,9 +117,6 @@ type ObservableState<Value> = {
122
117
  beacon: BeaconState<Value>;
123
118
  };
124
119
 
125
- /**
126
- * An observer receives notifications from an observable
127
- */
128
120
  type Observer<Value> = {
129
121
  /**
130
122
  * Callback for when the observable is completed
@@ -140,28 +132,6 @@ type Observer<Value> = {
140
132
  next?: (value: Value) => void;
141
133
  };
142
134
 
143
- export type Subscription = {
144
- /**
145
- * Is the subscription active?
146
- */
147
- get active(): boolean;
148
-
149
- /**
150
- * Is the subscription closed?
151
- */
152
- get closed(): boolean;
153
-
154
- /**
155
- * Close the subscription
156
- */
157
- close(): void;
158
-
159
- /**
160
- * Unsubscribe from its observable
161
- */
162
- unsubscribe(): void;
163
- };
164
-
165
135
  // #endregion
166
136
 
167
137
  // #region Functions
@@ -178,12 +148,12 @@ export function beacon<Value>(value: Value, options?: BeaconOptions<Value>): Bea
178
148
  value,
179
149
  active: true,
180
150
  observable: undefined as never,
181
- observers: new Map(),
182
151
  options: getBeaconOptions(options),
152
+ subscriptions: getSubscriptions(),
183
153
  };
184
154
 
185
155
  const instance = {
186
- close: (): void => {
156
+ deactivate: (): void => {
187
157
  finishBeacon(state, false);
188
158
  },
189
159
  emit: (value: Value, finish?: boolean): void => {
@@ -206,10 +176,6 @@ export function beacon<Value>(value: Value, options?: BeaconOptions<Value>): Bea
206
176
  enumerable: true,
207
177
  get: () => state.active,
208
178
  },
209
- closed: {
210
- enumerable: true,
211
- get: () => !state.active,
212
- },
213
179
  observable: {
214
180
  enumerable: true,
215
181
  get: () => {
@@ -238,21 +204,15 @@ function finishBeacon<Value>(state: BeaconState<Value>, emit: boolean): void {
238
204
 
239
205
  state.active = false;
240
206
 
241
- const entries = [...state.observers.entries()];
242
- const {length} = entries;
243
-
244
- for (let index = 0; index < length; index += 1) {
245
- const [subscription, observer] = entries[index];
246
-
207
+ for (const [, observer] of state.subscriptions.values.to.any) {
247
208
  if (emit) {
248
209
  observer.complete?.();
249
210
  }
250
-
251
- subscription.close();
252
211
  }
253
212
 
254
- state.observable?.close();
255
- state.observers.clear();
213
+ clearSubscriptions(state.subscriptions);
214
+
215
+ state.observable?.deactivate();
256
216
 
257
217
  state.observable = undefined as never;
258
218
  }
@@ -317,16 +277,6 @@ export function isObservable<Value = unknown>(value: unknown): value is Observab
317
277
  return isBeaconInstance<Observable<Value>>(NAME_OBSERVABLE, value);
318
278
  }
319
279
 
320
- /**
321
- * Is the value a subscription?
322
- *
323
- * @param value Value to check
324
- * @returns `true` if the value is a subscription, otherwise `false`
325
- */
326
- export function isSubscription(value: unknown): value is Subscription {
327
- return isBeaconInstance<Subscription>(NAME_SUBSCRIPTION, value);
328
- }
329
-
330
280
  function observe<Value>(beacon: BeaconState<Value>): Observable<Value> {
331
281
  const state: ObservableState<Value> = {
332
282
  beacon,
@@ -334,7 +284,7 @@ function observe<Value>(beacon: BeaconState<Value>): Observable<Value> {
334
284
  };
335
285
 
336
286
  const instance = {
337
- close: (): void => {
287
+ deactivate: (): void => {
338
288
  state.active = false;
339
289
  },
340
290
  subscribe(
@@ -347,9 +297,13 @@ function observe<Value>(beacon: BeaconState<Value>): Observable<Value> {
347
297
  }
348
298
 
349
299
  const observer = getObserver(first, second, third);
350
- const subscription = subscribe(state);
351
300
 
352
- beacon.observers.set(subscription, observer);
301
+ const subscription = getSubscription({
302
+ isActive: () => beacon.active && state.active,
303
+ property: beaconSubscription,
304
+ subscriptions: beacon.subscriptions,
305
+ value: observer,
306
+ });
353
307
 
354
308
  observer.next?.(beacon.value);
355
309
 
@@ -366,53 +320,11 @@ function observe<Value>(beacon: BeaconState<Value>): Observable<Value> {
366
320
  enumerable: true,
367
321
  get: () => beacon.active && state.active,
368
322
  },
369
- closed: {
370
- enumerable: true,
371
- get: () => !beacon.active || !state.active,
372
- },
373
323
  });
374
324
 
375
325
  return Object.freeze(instance) as Observable<Value>;
376
326
  }
377
327
 
378
- function subscribe<Value>(observable: ObservableState<Value>): Subscription {
379
- function unsubscribe(): void {
380
- if (active) {
381
- active = false;
382
-
383
- observable.beacon.observers.delete(instance as Subscription);
384
- }
385
- }
386
-
387
- let active = true;
388
-
389
- const instance = {
390
- close: (): void => {
391
- unsubscribe();
392
- },
393
- unsubscribe: (): void => {
394
- unsubscribe();
395
- },
396
- };
397
-
398
- Object.defineProperties(instance, {
399
- [KEY_BEACON]: {
400
- enumerable: false,
401
- value: NAME_SUBSCRIPTION,
402
- },
403
- active: {
404
- enumerable: true,
405
- get: () => observable.beacon.active && observable.active && active,
406
- },
407
- closed: {
408
- enumerable: true,
409
- get: () => !observable.beacon.active || !observable.active || !active,
410
- },
411
- });
412
-
413
- return Object.freeze(instance) as Subscription;
414
- }
415
-
416
328
  function update<Value>(
417
329
  type: keyof Observer<never>,
418
330
  state: BeaconState<Value>,
@@ -431,7 +343,7 @@ function update<Value>(
431
343
  state.value = value as Value;
432
344
  }
433
345
 
434
- for (const [, observer] of state.observers) {
346
+ for (const [, observer] of state.subscriptions.values.to.any) {
435
347
  observer[type]?.(value as never);
436
348
  }
437
349
 
@@ -454,10 +366,13 @@ const NAME_BEACON = 'beacon';
454
366
 
455
367
  const NAME_OBSERVABLE = 'observable';
456
368
 
457
- const NAME_SUBSCRIPTION = 'subscription';
458
-
459
369
  const TYPE_ERROR = 'error';
460
370
 
461
371
  const TYPE_NEXT = 'next';
462
372
 
373
+ const beaconSubscription: SubscriptionProperty = {
374
+ key: KEY_BEACON,
375
+ value: 'subscription',
376
+ };
377
+
463
378
  // #endregion
@@ -1,88 +1,137 @@
1
- import type {Alpha, HSLAColor, HSLColor, HWBAColor, HWBColor, RGBAColor, RGBColor} from './models';
2
-
3
- // #region Variables
4
-
5
- export const ALPHA_FULL_HEX_SHORT = 'f';
6
-
7
- export const ALPHA_FULL_HEX_LONG = `${ALPHA_FULL_HEX_SHORT}${ALPHA_FULL_HEX_SHORT}`;
1
+ import type {
2
+ Alpha,
3
+ ColorTypeExtended,
4
+ HSLAColor,
5
+ HSLColor,
6
+ HWBAColor,
7
+ HWBColor,
8
+ RGBAColor,
9
+ RGBColor,
10
+ } from './models';
11
+
12
+ // #region Types
13
+
14
+ type ColorTypes = {
15
+ all: Set<'alpha' | ColorTypeExtended>;
16
+ hex: 'hex';
17
+ hexa: 'hexa';
18
+ hsl: 'hsl';
19
+ hsla: 'hsla';
20
+ hwb: 'hwb';
21
+ hwba: 'hwba';
22
+ rgb: 'rgb';
23
+ rgba: 'rgba';
24
+ };
8
25
 
9
- export const ALPHA_NONE_HEX = '00';
26
+ // #endregion
10
27
 
11
- export const ALPHA_NONE_VALUE = 0;
28
+ // #region Variables
12
29
 
13
- export const DEFAULT_ALPHA: Alpha = {
14
- hex: ALPHA_FULL_HEX_LONG,
15
- value: 100,
30
+ export const COLOR_ALPHA = {
31
+ fullHexShort: 'f',
32
+ fullHexLong: 'ff',
33
+ name: 'alpha',
34
+ noneHex: '00',
35
+ noneValue: 0,
16
36
  };
17
37
 
18
- export const DEFAULT_HSL: HSLColor = {
19
- hue: 0,
20
- saturation: 0,
21
- lightness: 0,
38
+ export const COLOR_DEFAULTS = {
39
+ alpha: {
40
+ hex: COLOR_ALPHA.fullHexLong,
41
+ value: 100,
42
+ },
43
+ hexBlack: '000000',
44
+ hexWhite: 'ffffff',
45
+ hsl: {
46
+ hue: 0,
47
+ saturation: 0,
48
+ lightness: 0,
49
+ },
50
+ hwb: {
51
+ hue: 0,
52
+ whiteness: 0,
53
+ blackness: 100,
54
+ },
55
+ rgb: {
56
+ blue: 0,
57
+ green: 0,
58
+ red: 0,
59
+ },
22
60
  };
23
61
 
24
- export const DEFAULT_HWB: HWBColor = {
25
- hue: 0,
26
- whiteness: 0,
27
- blackness: 100,
62
+ export const COLOR_EXPRESSION = {
63
+ alphaHex: /^([a-f0-9]{1,2})$/i,
64
+ hexLong: /^#?([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?$/i,
65
+ hexShort: /^#?([a-f0-9]{3,4})$/i,
66
+ prefix: /^#/,
28
67
  };
29
68
 
30
- export const DEFAULT_RGB: RGBColor = {
31
- blue: 0,
32
- green: 0,
33
- red: 0,
69
+ export const COLOR_LENGTHS = {
70
+ hexLong: 6,
71
+ hexShort: 3,
34
72
  };
35
73
 
36
- export const EXPRESSION_HEX_LONG = /^#?([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?$/i;
37
-
38
- export const EXPRESSION_HEX_SHORT = /^#?([a-f0-9]{3,4})$/i;
39
-
40
- export const EXPRESSION_PREFIX = /^#/;
41
-
42
- export const HEX_BLACK = '000000';
43
-
44
- export const HEX_WHITE = 'ffffff';
45
-
46
- export const LENGTH_LONG = 6;
47
-
48
- export const LENGTH_SHORT = 3;
49
-
50
- export const KEYS_HSL: Array<keyof HSLColor> = ['hue', 'saturation', 'lightness'];
51
-
52
- export const KEYS_HSLA: Array<keyof HSLAColor> = [...KEYS_HSL, 'alpha'];
74
+ export const COLOR_KEYS = {
75
+ hsl: ['hue', 'saturation', 'lightness'] as Array<keyof HSLColor>,
76
+ hsla: [] as Array<keyof HSLAColor>,
77
+ hwb: ['hue', 'whiteness', 'blackness'] as Array<keyof HWBColor>,
78
+ hwba: [] as Array<keyof HWBAColor>,
79
+ rgb: ['red', 'green', 'blue'] as Array<keyof RGBColor>,
80
+ rgba: [] as Array<keyof RGBAColor>,
81
+ };
53
82
 
54
- export const KEYS_HWB: Array<keyof HWBColor> = ['hue', 'whiteness', 'blackness'];
83
+ COLOR_KEYS.hsla = [...COLOR_KEYS.hsl, COLOR_ALPHA.name as keyof Alpha] as Array<keyof HSLAColor>;
55
84
 
56
- export const KEYS_HWBA: Array<keyof HWBAColor> = [...KEYS_HWB, 'alpha'];
85
+ COLOR_KEYS.hwba = [...COLOR_KEYS.hwb, COLOR_ALPHA.name as keyof Alpha] as Array<keyof HWBAColor>;
57
86
 
58
- export const KEYS_RGB: Array<keyof RGBColor> = ['red', 'green', 'blue'];
87
+ COLOR_KEYS.rgba = [...COLOR_KEYS.rgb, COLOR_ALPHA.name as keyof Alpha] as Array<keyof RGBAColor>;
59
88
 
60
- export const KEYS_RGBA: Array<keyof RGBAColor> = [...KEYS_RGB, 'alpha'];
89
+ export const COLOR_MAX = {
90
+ degree: 360,
91
+ hex: 255,
92
+ percent: 100,
93
+ };
61
94
 
62
- export const MAX_DEGREE = 360;
95
+ export const COLOR_PROPERTY = {
96
+ name: '$color',
97
+ subscription: 'subscription',
98
+ };
63
99
 
64
- export const MAX_HEX = 255;
100
+ export const COLOR_TYPE: ColorTypes = {
101
+ all: undefined as unknown as Set<'alpha' | ColorTypeExtended>,
102
+ hex: 'hex',
103
+ hexa: 'hexa',
104
+ hsl: 'hsl',
105
+ hsla: 'hsla',
106
+ hwb: 'hwb',
107
+ hwba: 'hwba',
108
+ rgb: 'rgb',
109
+ rgba: 'rgba',
110
+ };
65
111
 
66
- export const MAX_PERCENT = 100;
112
+ COLOR_TYPE.all = new Set([
113
+ COLOR_ALPHA.name as 'alpha',
114
+ COLOR_TYPE.hex,
115
+ COLOR_TYPE.hexa,
116
+ COLOR_TYPE.hsl,
117
+ COLOR_TYPE.hsla,
118
+ COLOR_TYPE.hwb,
119
+ COLOR_TYPE.hwba,
120
+ COLOR_TYPE.rgb,
121
+ COLOR_TYPE.rgba,
122
+ ] as Array<'alpha' | ColorTypeExtended>);
67
123
 
68
124
  // https://www.w3.org/TR/WCAG20/#relativeluminancedef
69
-
70
- export const SRGB_LUMINANCE_BLUE = 0.0722;
71
-
72
- export const SRGB_LUMINANCE_EXPONENT = 2.4;
73
-
74
- export const SRGB_LUMINANCE_GREEN = 0.7152;
75
-
76
- export const SRGB_LUMINANCE_MINIMUM = 0.03928;
77
-
78
- export const SRGB_LUMINANCE_MODIFIER = 1.055;
79
-
80
- export const SRGB_LUMINANCE_MULTIPLIER = 12.92;
81
-
82
- export const SRGB_LUMINANCE_OFFSET = 0.055;
83
-
84
- export const SRGB_LUMINANCE_RED = 0.2126;
85
-
86
- export const SRGB_LUMINANCE_THRESHOLD = 0.625;
125
+ export const COLOR_SRGB = {
126
+ luminanceBlue: 0.0722,
127
+ luminanceExponent: 2.4,
128
+ luminanceGreen: 0.7152,
129
+ luminanceMinimum: 0.03928,
130
+ luminanceModifier: 1.055,
131
+ luminanceMultiplier: 12.92,
132
+ luminanceOffset: 0.055,
133
+ luminanceRed: 0.2126,
134
+ luminanceThreshold: 0.625,
135
+ };
87
136
 
88
137
  // #endregion