@dicebear/core 10.0.0-rc.2 → 10.0.0-rc.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 (59) hide show
  1. package/lib/Avatar.d.ts +17 -1
  2. package/lib/Avatar.js +23 -5
  3. package/lib/Error/CircularColorReferenceError.d.ts +4 -0
  4. package/lib/Error/CircularColorReferenceError.js +4 -0
  5. package/lib/Error/OptionsValidationError.d.ts +3 -0
  6. package/lib/Error/OptionsValidationError.js +3 -0
  7. package/lib/Error/StyleValidationError.d.ts +3 -0
  8. package/lib/Error/StyleValidationError.js +3 -0
  9. package/lib/Error/ValidationError.d.ts +4 -0
  10. package/lib/Error/ValidationError.js +4 -0
  11. package/lib/Options.d.ts +39 -18
  12. package/lib/Options.js +64 -164
  13. package/lib/OptionsDescriptor.d.ts +8 -0
  14. package/lib/OptionsDescriptor.js +14 -6
  15. package/lib/Prng/Fnv1a.d.ts +14 -0
  16. package/lib/Prng/Fnv1a.js +14 -3
  17. package/lib/Prng/Mulberry32.d.ts +22 -0
  18. package/lib/Prng/Mulberry32.js +22 -8
  19. package/lib/Prng.d.ts +35 -0
  20. package/lib/Prng.js +35 -6
  21. package/lib/Renderer.d.ts +11 -2
  22. package/lib/Renderer.js +60 -54
  23. package/lib/Resolver.d.ts +62 -0
  24. package/lib/Resolver.js +203 -0
  25. package/lib/Style/Canvas.d.ts +14 -0
  26. package/lib/Style/Canvas.js +14 -0
  27. package/lib/Style/Color.d.ts +14 -0
  28. package/lib/Style/Color.js +14 -0
  29. package/lib/Style/Component.d.ts +50 -1
  30. package/lib/Style/Component.js +88 -9
  31. package/lib/Style/ComponentTranslate.d.ts +10 -0
  32. package/lib/Style/ComponentTranslate.js +10 -0
  33. package/lib/Style/ComponentVariant.d.ts +10 -0
  34. package/lib/Style/ComponentVariant.js +10 -0
  35. package/lib/Style/Element.d.ts +25 -0
  36. package/lib/Style/Element.js +25 -0
  37. package/lib/Style/Meta.d.ts +16 -0
  38. package/lib/Style/Meta.js +16 -0
  39. package/lib/Style/MetaCreator.d.ts +9 -0
  40. package/lib/Style/MetaCreator.js +9 -0
  41. package/lib/Style/MetaLicense.d.ts +12 -0
  42. package/lib/Style/MetaLicense.js +12 -0
  43. package/lib/Style/MetaSource.d.ts +10 -0
  44. package/lib/Style/MetaSource.js +10 -0
  45. package/lib/Style.d.ts +37 -1
  46. package/lib/Style.js +90 -6
  47. package/lib/StyleDefinition.d.ts +8 -3
  48. package/lib/StyleOptions.d.ts +12 -10
  49. package/lib/Utils/Color.d.ts +28 -0
  50. package/lib/Utils/Color.js +28 -8
  51. package/lib/Utils/Initials.d.ts +10 -0
  52. package/lib/Utils/Initials.js +10 -3
  53. package/lib/Utils/License.d.ts +14 -0
  54. package/lib/Utils/License.js +14 -0
  55. package/lib/Utils/Xml.d.ts +6 -0
  56. package/lib/Utils/Xml.js +6 -0
  57. package/lib/Validator/OptionsValidator.js +1549 -1675
  58. package/lib/Validator/StyleValidator.js +3355 -3115
  59. package/package.json +2 -2
package/lib/Avatar.d.ts CHANGED
@@ -5,11 +5,27 @@ interface AvatarJson<D = unknown> {
5
5
  readonly svg: string;
6
6
  readonly options: StyleOptions<UnwrapStyle<D>>;
7
7
  }
8
+ /**
9
+ * Top-level entry point for rendering an avatar from a style and options.
10
+ *
11
+ * Construction immediately resolves and renders the SVG; the various
12
+ * accessor methods return different serializations of that result.
13
+ */
8
14
  export declare class Avatar<D = unknown> {
9
15
  #private;
10
- constructor(style: D, options?: StyleOptions<UnwrapStyle<D>>);
16
+ constructor(styleInput: D, optionsInput?: StyleOptions<UnwrapStyle<D>>);
17
+ /**
18
+ * Returns the rendered SVG markup.
19
+ */
11
20
  toString(): string;
21
+ /**
22
+ * Returns the avatar as a JSON-serializable object containing the SVG and
23
+ * the fully resolved options used to render it.
24
+ */
12
25
  toJSON(): AvatarJson<D>;
26
+ /**
27
+ * Returns the SVG encoded as a `data:image/svg+xml` URI.
28
+ */
13
29
  toDataUri(): string;
14
30
  }
15
31
  export {};
package/lib/Avatar.js CHANGED
@@ -12,25 +12,43 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
12
12
  var _Avatar_svg, _Avatar_resolvedOptions;
13
13
  import { Style } from './Style.js';
14
14
  import { Options } from './Options.js';
15
+ import { Resolver } from './Resolver.js';
15
16
  import { Renderer } from './Renderer.js';
17
+ /**
18
+ * Top-level entry point for rendering an avatar from a style and options.
19
+ *
20
+ * Construction immediately resolves and renders the SVG; the various
21
+ * accessor methods return different serializations of that result.
22
+ */
16
23
  export class Avatar {
17
- constructor(style, options) {
24
+ constructor(styleInput, optionsInput) {
18
25
  _Avatar_svg.set(this, void 0);
19
26
  _Avatar_resolvedOptions.set(this, void 0);
20
- const resolvedStyle = style instanceof Style ? style : new Style(style);
21
- const resolvedOptions = new Options(resolvedStyle, options ?? {});
22
- __classPrivateFieldSet(this, _Avatar_svg, new Renderer(resolvedStyle, resolvedOptions).render(), "f");
23
- __classPrivateFieldSet(this, _Avatar_resolvedOptions, resolvedOptions.resolved(), "f");
27
+ const style = styleInput instanceof Style ? styleInput : new Style(styleInput);
28
+ const options = new Options(optionsInput);
29
+ const resolver = new Resolver(style, options);
30
+ __classPrivateFieldSet(this, _Avatar_svg, new Renderer(style, resolver).render(), "f");
31
+ __classPrivateFieldSet(this, _Avatar_resolvedOptions, resolver.resolved(), "f");
24
32
  }
33
+ /**
34
+ * Returns the rendered SVG markup.
35
+ */
25
36
  toString() {
26
37
  return __classPrivateFieldGet(this, _Avatar_svg, "f");
27
38
  }
39
+ /**
40
+ * Returns the avatar as a JSON-serializable object containing the SVG and
41
+ * the fully resolved options used to render it.
42
+ */
28
43
  toJSON() {
29
44
  return {
30
45
  svg: __classPrivateFieldGet(this, _Avatar_svg, "f"),
31
46
  options: structuredClone(__classPrivateFieldGet(this, _Avatar_resolvedOptions, "f")),
32
47
  };
33
48
  }
49
+ /**
50
+ * Returns the SVG encoded as a `data:image/svg+xml` URI.
51
+ */
34
52
  toDataUri() {
35
53
  return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(__classPrivateFieldGet(this, _Avatar_svg, "f"))}`;
36
54
  }
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Thrown when a color in the style definition references itself, directly or
3
+ * indirectly. The {@link chain} field reproduces the resolution path.
4
+ */
1
5
  export declare class CircularColorReferenceError extends Error {
2
6
  readonly chain: readonly string[];
3
7
  constructor(chain: readonly string[]);
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Thrown when a color in the style definition references itself, directly or
3
+ * indirectly. The {@link chain} field reproduces the resolution path.
4
+ */
1
5
  export class CircularColorReferenceError extends Error {
2
6
  constructor(chain) {
3
7
  const path = chain.join(' → ');
@@ -1,5 +1,8 @@
1
1
  import { ValidationError } from './ValidationError.js';
2
2
  import type { ValidationErrorDetail } from './ValidationError.js';
3
+ /**
4
+ * Thrown when avatar options fail schema validation.
5
+ */
3
6
  export declare class OptionsValidationError extends ValidationError {
4
7
  constructor(details: readonly ValidationErrorDetail[]);
5
8
  }
@@ -1,4 +1,7 @@
1
1
  import { ValidationError } from './ValidationError.js';
2
+ /**
3
+ * Thrown when avatar options fail schema validation.
4
+ */
2
5
  export class OptionsValidationError extends ValidationError {
3
6
  constructor(details) {
4
7
  super('Invalid options', details);
@@ -1,5 +1,8 @@
1
1
  import { ValidationError } from './ValidationError.js';
2
2
  import type { ValidationErrorDetail } from './ValidationError.js';
3
+ /**
4
+ * Thrown when a style definition fails schema validation.
5
+ */
3
6
  export declare class StyleValidationError extends ValidationError {
4
7
  constructor(details: readonly ValidationErrorDetail[]);
5
8
  }
@@ -1,4 +1,7 @@
1
1
  import { ValidationError } from './ValidationError.js';
2
+ /**
3
+ * Thrown when a style definition fails schema validation.
4
+ */
2
5
  export class StyleValidationError extends ValidationError {
3
6
  constructor(details) {
4
7
  super('Invalid style definition', details);
@@ -2,6 +2,10 @@ export interface ValidationErrorDetail {
2
2
  readonly message?: string;
3
3
  readonly instancePath?: string;
4
4
  }
5
+ /**
6
+ * Base class for schema validation errors. Carries the prefix in `message`
7
+ * and the per-field failures in {@link details}.
8
+ */
5
9
  export declare class ValidationError extends Error {
6
10
  readonly details: readonly ValidationErrorDetail[];
7
11
  constructor(prefix: string, details: readonly ValidationErrorDetail[]);
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Base class for schema validation errors. Carries the prefix in `message`
3
+ * and the per-field failures in {@link details}.
4
+ */
1
5
  export class ValidationError extends Error {
2
6
  constructor(prefix, details) {
3
7
  const parts = [];
package/lib/Options.d.ts CHANGED
@@ -1,23 +1,44 @@
1
- import type { Style } from './Style.js';
2
- import type { StyleOptionsFlipValue, StyleOptionsColorFillValue, StyleOptions } from './StyleOptions.js';
1
+ import type { StyleOptions, StyleOptionsFlipValue, StyleOptionsColorFillValue } from './StyleOptions.js';
2
+ /**
3
+ * Validates the raw user-supplied options and exposes them through typed
4
+ * accessors. Each accessor returns the user's input in a normalized form
5
+ * (always an array for options that accept either a scalar or an array, or
6
+ * `undefined` when the option is not set), so consumers — chiefly
7
+ * {@link Resolver} — never have to do their own normalization.
8
+ *
9
+ * Resolution against the style definition and the PRNG happens in
10
+ * {@link Resolver}; this class is purely about reading user input.
11
+ */
3
12
  export declare class Options<D = unknown> {
4
13
  #private;
5
- constructor(style: Style<D>, data: StyleOptions<D>);
6
- seed(): string;
14
+ constructor(data?: StyleOptions<D>);
15
+ seed(): string | undefined;
7
16
  size(): number | undefined;
8
- idRandomization(): boolean;
17
+ idRandomization(): boolean | undefined;
9
18
  title(): string | undefined;
10
- flip(): StyleOptionsFlipValue;
11
- fontFamily(): string;
12
- fontWeight(): number;
13
- scale(): number;
14
- borderRadius(): number;
15
- variant(name: string): string | undefined;
16
- color(name: string): readonly string[];
17
- colorFill(name: string): StyleOptionsColorFillValue;
18
- colorAngle(name: string): number;
19
- rotate(name?: string): number;
20
- translateX(name?: string): number;
21
- translateY(name?: string): number;
22
- resolved(): StyleOptions<D>;
19
+ flip(): readonly StyleOptionsFlipValue[];
20
+ fontFamily(): readonly string[];
21
+ fontWeight(): readonly number[];
22
+ scale(): readonly number[];
23
+ borderRadius(): readonly number[];
24
+ rotate(): readonly number[];
25
+ translateX(): readonly number[];
26
+ translateY(): readonly number[];
27
+ /**
28
+ * Returns the user-set variant constraint for `name`:
29
+ * - `undefined` when the user did not set `${name}Variant`,
30
+ * - `string[]` when the user gave a string or string list (each weighted 1),
31
+ * - `Record<string, number>` when the user gave a weighted map.
32
+ */
33
+ componentVariant(name: string): readonly string[] | Readonly<Record<string, number>> | undefined;
34
+ componentProbability(name: string): number | undefined;
35
+ /**
36
+ * Asymmetric on purpose: returns `undefined` (rather than `[]`) when
37
+ * `${name}Color` is unset so the resolver can fall back to the style
38
+ * definition's color values.
39
+ */
40
+ color(name: string): readonly string[] | undefined;
41
+ colorFill(name: string): readonly StyleOptionsColorFillValue[];
42
+ colorAngle(name: string): readonly number[];
43
+ colorFillStops(name: string): readonly number[];
23
44
  }
package/lib/Options.js CHANGED
@@ -9,204 +9,104 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _Options_instances, _Options_data, _Options_style, _Options_prng, _Options_colorResolving, _Options_result, _Options_numericComponentOption, _Options_probability, _Options_isVisible, _Options_colorFillStops, _Options_resolveColor, _Options_get, _Options_memo, _Options_toArray;
12
+ var _Options_instances, _Options_data, _Options_dynamic, _Options_asArray;
13
13
  import { OptionsValidator } from './Validator/OptionsValidator.js';
14
- import { Prng } from './Prng.js';
15
- import { Color } from './Utils/Color.js';
16
- import { CircularColorReferenceError } from './Error/CircularColorReferenceError.js';
14
+ /**
15
+ * Validates the raw user-supplied options and exposes them through typed
16
+ * accessors. Each accessor returns the user's input in a normalized form
17
+ * (always an array for options that accept either a scalar or an array, or
18
+ * `undefined` when the option is not set), so consumers — chiefly
19
+ * {@link Resolver} — never have to do their own normalization.
20
+ *
21
+ * Resolution against the style definition and the PRNG happens in
22
+ * {@link Resolver}; this class is purely about reading user input.
23
+ */
17
24
  export class Options {
18
- constructor(style, data) {
25
+ constructor(data = {}) {
19
26
  _Options_instances.add(this);
20
27
  _Options_data.set(this, void 0);
21
- _Options_style.set(this, void 0);
22
- _Options_prng.set(this, void 0);
23
- _Options_colorResolving.set(this, []);
24
- _Options_result.set(this, {});
25
28
  OptionsValidator.validate(data);
26
29
  __classPrivateFieldSet(this, _Options_data, structuredClone(data), "f");
27
- __classPrivateFieldSet(this, _Options_style, style, "f");
28
- __classPrivateFieldSet(this, _Options_prng, new Prng(this.seed()), "f");
29
30
  }
30
31
  seed() {
31
- return __classPrivateFieldGet(this, _Options_instances, "m", _Options_memo).call(this, 'seed', () => __classPrivateFieldGet(this, _Options_data, "f").seed ?? '');
32
+ return __classPrivateFieldGet(this, _Options_data, "f").seed;
32
33
  }
33
34
  size() {
34
- return __classPrivateFieldGet(this, _Options_instances, "m", _Options_memo).call(this, 'size', () => __classPrivateFieldGet(this, _Options_data, "f").size);
35
+ return __classPrivateFieldGet(this, _Options_data, "f").size;
35
36
  }
36
37
  idRandomization() {
37
- return __classPrivateFieldGet(this, _Options_instances, "m", _Options_memo).call(this, 'idRandomization', () => __classPrivateFieldGet(this, _Options_data, "f").idRandomization ?? false);
38
+ return __classPrivateFieldGet(this, _Options_data, "f").idRandomization;
38
39
  }
39
40
  title() {
40
- return __classPrivateFieldGet(this, _Options_instances, "m", _Options_memo).call(this, 'title', () => __classPrivateFieldGet(this, _Options_data, "f").title);
41
+ return __classPrivateFieldGet(this, _Options_data, "f").title;
41
42
  }
42
43
  flip() {
43
- return __classPrivateFieldGet(this, _Options_instances, "m", _Options_memo).call(this, 'flip', () => __classPrivateFieldGet(this, _Options_prng, "f").pick('flip', __classPrivateFieldGet(this, _Options_instances, "m", _Options_toArray).call(this, __classPrivateFieldGet(this, _Options_data, "f").flip)) ?? 'none');
44
+ return __classPrivateFieldGet(this, _Options_instances, "m", _Options_asArray).call(this, __classPrivateFieldGet(this, _Options_data, "f").flip);
44
45
  }
45
46
  fontFamily() {
46
- return __classPrivateFieldGet(this, _Options_instances, "m", _Options_memo).call(this, 'fontFamily', () => __classPrivateFieldGet(this, _Options_prng, "f").pick('fontFamily', __classPrivateFieldGet(this, _Options_instances, "m", _Options_toArray).call(this, __classPrivateFieldGet(this, _Options_data, "f").fontFamily)) ??
47
- 'system-ui');
47
+ return __classPrivateFieldGet(this, _Options_instances, "m", _Options_asArray).call(this, __classPrivateFieldGet(this, _Options_data, "f").fontFamily);
48
48
  }
49
49
  fontWeight() {
50
- return __classPrivateFieldGet(this, _Options_instances, "m", _Options_memo).call(this, 'fontWeight', () => __classPrivateFieldGet(this, _Options_prng, "f").pick('fontWeight', __classPrivateFieldGet(this, _Options_instances, "m", _Options_toArray).call(this, __classPrivateFieldGet(this, _Options_data, "f").fontWeight)) ??
51
- 400);
50
+ return __classPrivateFieldGet(this, _Options_instances, "m", _Options_asArray).call(this, __classPrivateFieldGet(this, _Options_data, "f").fontWeight);
52
51
  }
53
52
  scale() {
54
- return __classPrivateFieldGet(this, _Options_instances, "m", _Options_memo).call(this, 'scale', () => __classPrivateFieldGet(this, _Options_prng, "f").float('scale', __classPrivateFieldGet(this, _Options_instances, "m", _Options_toArray).call(this, __classPrivateFieldGet(this, _Options_data, "f").scale)) ?? 1);
53
+ return __classPrivateFieldGet(this, _Options_instances, "m", _Options_asArray).call(this, __classPrivateFieldGet(this, _Options_data, "f").scale);
55
54
  }
56
55
  borderRadius() {
57
- return __classPrivateFieldGet(this, _Options_instances, "m", _Options_memo).call(this, 'borderRadius', () => __classPrivateFieldGet(this, _Options_prng, "f").float('borderRadius', __classPrivateFieldGet(this, _Options_instances, "m", _Options_toArray).call(this, __classPrivateFieldGet(this, _Options_data, "f").borderRadius)) ?? 0);
58
- }
59
- // Selects a variant for the given component. Depending on what was passed
60
- // as `${name}Variant` in the input data:
61
- // - undefined: PRNG picks from all style variants using their weights
62
- // - string or string[]: PRNG picks from the given subset (weight 1 each)
63
- // - Record<string, number>: PRNG picks using the provided weights
64
- // Only variants that exist in the style definition are considered.
65
- variant(name) {
66
- return __classPrivateFieldGet(this, _Options_instances, "m", _Options_memo).call(this, `${name}Variant`, () => {
67
- if (!__classPrivateFieldGet(this, _Options_instances, "m", _Options_isVisible).call(this, name)) {
68
- return undefined;
69
- }
70
- const component = __classPrivateFieldGet(this, _Options_style, "f").components().get(name);
71
- if (!component) {
72
- return undefined;
73
- }
74
- const raw = __classPrivateFieldGet(this, _Options_instances, "m", _Options_get).call(this, `${name}Variant`);
75
- const variants = component.variants();
76
- let entries;
77
- if (raw === undefined) {
78
- entries = Array.from(variants).map(([v, variant]) => [
79
- v,
80
- variant.weight(),
81
- ]);
82
- }
83
- else if (typeof raw === 'string' || Array.isArray(raw)) {
84
- entries = __classPrivateFieldGet(this, _Options_instances, "m", _Options_toArray).call(this, raw)
85
- .filter((v) => variants.has(v))
86
- .map((v) => [v, 1]);
87
- }
88
- else {
89
- entries = Object.entries(raw).filter(([v]) => variants.has(v));
90
- }
91
- return __classPrivateFieldGet(this, _Options_prng, "f").weightedPick(`${name}Variant`, entries);
92
- });
56
+ return __classPrivateFieldGet(this, _Options_instances, "m", _Options_asArray).call(this, __classPrivateFieldGet(this, _Options_data, "f").borderRadius);
57
+ }
58
+ rotate() {
59
+ return __classPrivateFieldGet(this, _Options_instances, "m", _Options_asArray).call(this, __classPrivateFieldGet(this, _Options_data, "f").rotate);
60
+ }
61
+ translateX() {
62
+ return __classPrivateFieldGet(this, _Options_instances, "m", _Options_asArray).call(this, __classPrivateFieldGet(this, _Options_data, "f").translateX);
63
+ }
64
+ translateY() {
65
+ return __classPrivateFieldGet(this, _Options_instances, "m", _Options_asArray).call(this, __classPrivateFieldGet(this, _Options_data, "f").translateY);
66
+ }
67
+ /**
68
+ * Returns the user-set variant constraint for `name`:
69
+ * - `undefined` when the user did not set `${name}Variant`,
70
+ * - `string[]` when the user gave a string or string list (each weighted 1),
71
+ * - `Record<string, number>` when the user gave a weighted map.
72
+ */
73
+ componentVariant(name) {
74
+ const raw = __classPrivateFieldGet(this, _Options_instances, "m", _Options_dynamic).call(this, `${name}Variant`);
75
+ if (raw === undefined) {
76
+ return undefined;
77
+ }
78
+ if (typeof raw === 'string' || Array.isArray(raw)) {
79
+ return __classPrivateFieldGet(this, _Options_instances, "m", _Options_asArray).call(this, raw);
80
+ }
81
+ return raw;
82
+ }
83
+ componentProbability(name) {
84
+ return __classPrivateFieldGet(this, _Options_instances, "m", _Options_dynamic).call(this, `${name}Probability`);
93
85
  }
86
+ /**
87
+ * Asymmetric on purpose: returns `undefined` (rather than `[]`) when
88
+ * `${name}Color` is unset so the resolver can fall back to the style
89
+ * definition's color values.
90
+ */
94
91
  color(name) {
95
- return __classPrivateFieldGet(this, _Options_instances, "m", _Options_memo).call(this, `${name}Color`, () => __classPrivateFieldGet(this, _Options_instances, "m", _Options_resolveColor).call(this, name));
92
+ const raw = __classPrivateFieldGet(this, _Options_instances, "m", _Options_dynamic).call(this, `${name}Color`);
93
+ return raw === undefined
94
+ ? undefined
95
+ : __classPrivateFieldGet(this, _Options_instances, "m", _Options_asArray).call(this, raw);
96
96
  }
97
97
  colorFill(name) {
98
- const key = `${name}ColorFill`;
99
- return __classPrivateFieldGet(this, _Options_instances, "m", _Options_memo).call(this, key, () => {
100
- const raw = __classPrivateFieldGet(this, _Options_instances, "m", _Options_get).call(this, key);
101
- return __classPrivateFieldGet(this, _Options_prng, "f").pick(key, __classPrivateFieldGet(this, _Options_instances, "m", _Options_toArray).call(this, raw)) ?? 'solid';
102
- });
98
+ return __classPrivateFieldGet(this, _Options_instances, "m", _Options_asArray).call(this, __classPrivateFieldGet(this, _Options_instances, "m", _Options_dynamic).call(this, `${name}ColorFill`));
103
99
  }
104
100
  colorAngle(name) {
105
- const key = `${name}ColorAngle`;
106
- return __classPrivateFieldGet(this, _Options_instances, "m", _Options_memo).call(this, key, () => {
107
- const raw = __classPrivateFieldGet(this, _Options_instances, "m", _Options_get).call(this, key);
108
- return __classPrivateFieldGet(this, _Options_prng, "f").float(key, __classPrivateFieldGet(this, _Options_instances, "m", _Options_toArray).call(this, raw)) ?? 0;
109
- });
101
+ return __classPrivateFieldGet(this, _Options_instances, "m", _Options_asArray).call(this, __classPrivateFieldGet(this, _Options_instances, "m", _Options_dynamic).call(this, `${name}ColorAngle`));
110
102
  }
111
- rotate(name) {
112
- return __classPrivateFieldGet(this, _Options_instances, "m", _Options_numericComponentOption).call(this, 'rotate', name, (c) => c.rotate());
113
- }
114
- translateX(name) {
115
- return __classPrivateFieldGet(this, _Options_instances, "m", _Options_numericComponentOption).call(this, 'translateX', name, (c) => c.translate().x());
116
- }
117
- translateY(name) {
118
- return __classPrivateFieldGet(this, _Options_instances, "m", _Options_numericComponentOption).call(this, 'translateY', name, (c) => c.translate().y());
119
- }
120
- resolved() {
121
- return structuredClone(__classPrivateFieldGet(this, _Options_result, "f"));
103
+ colorFillStops(name) {
104
+ return __classPrivateFieldGet(this, _Options_instances, "m", _Options_asArray).call(this, __classPrivateFieldGet(this, _Options_instances, "m", _Options_dynamic).call(this, `${name}ColorFillStops`));
122
105
  }
123
106
  }
124
- _Options_data = new WeakMap(), _Options_style = new WeakMap(), _Options_prng = new WeakMap(), _Options_colorResolving = new WeakMap(), _Options_result = new WeakMap(), _Options_instances = new WeakSet(), _Options_numericComponentOption = function _Options_numericComponentOption(option, name, componentDefault) {
125
- const key = name
126
- ? `${name}${option.charAt(0).toUpperCase()}${option.slice(1)}`
127
- : option;
128
- return __classPrivateFieldGet(this, _Options_instances, "m", _Options_memo).call(this, key, () => {
129
- const raw = __classPrivateFieldGet(this, _Options_instances, "m", _Options_get).call(this, key);
130
- let values;
131
- if (raw === undefined && name) {
132
- const component = __classPrivateFieldGet(this, _Options_style, "f").components().get(name);
133
- values = component ? componentDefault(component) : [];
134
- }
135
- else {
136
- values = __classPrivateFieldGet(this, _Options_instances, "m", _Options_toArray).call(this, raw);
137
- }
138
- return __classPrivateFieldGet(this, _Options_prng, "f").float(key, values) ?? 0;
139
- });
140
- }, _Options_probability = function _Options_probability(name) {
141
- const raw = __classPrivateFieldGet(this, _Options_instances, "m", _Options_get).call(this, `${name}Probability`);
142
- if (raw !== undefined) {
143
- return raw;
144
- }
145
- return __classPrivateFieldGet(this, _Options_style, "f").components().get(name)?.probability() ?? 100;
146
- }, _Options_isVisible = function _Options_isVisible(name) {
147
- return __classPrivateFieldGet(this, _Options_prng, "f").bool(`${name}Probability`, __classPrivateFieldGet(this, _Options_instances, "m", _Options_probability).call(this, name));
148
- }, _Options_colorFillStops = function _Options_colorFillStops(name) {
149
- const raw = __classPrivateFieldGet(this, _Options_instances, "m", _Options_get).call(this, `${name}ColorFillStops`);
150
- const values = __classPrivateFieldGet(this, _Options_instances, "m", _Options_toArray).call(this, raw);
151
- return __classPrivateFieldGet(this, _Options_prng, "f").integer(`${name}ColorFillStops`, values) ?? 2;
152
- }, _Options_resolveColor = function _Options_resolveColor(name) {
153
- const raw = __classPrivateFieldGet(this, _Options_instances, "m", _Options_get).call(this, `${name}Color`);
154
- const styleColor = __classPrivateFieldGet(this, _Options_style, "f").colors().get(name);
155
- let source;
156
- if (raw === undefined) {
157
- source = styleColor ? styleColor.values() : [];
158
- }
159
- else {
160
- source = __classPrivateFieldGet(this, _Options_instances, "m", _Options_toArray).call(this, raw);
161
- }
162
- let candidates = source.map((c) => Color.toHex(c));
163
- const fill = this.colorFill(name);
164
- const stops = fill === 'solid' ? 1 : __classPrivateFieldGet(this, _Options_instances, "m", _Options_colorFillStops).call(this, name);
165
- if (!styleColor) {
166
- return __classPrivateFieldGet(this, _Options_prng, "f").shuffle(`${name}Color`, candidates).slice(0, stops);
167
- }
168
- // Detect circular references (e.g. a.contrastTo = b, b.contrastTo = a)
169
- if (__classPrivateFieldGet(this, _Options_colorResolving, "f").includes(name)) {
170
- throw new CircularColorReferenceError(__classPrivateFieldGet(this, _Options_colorResolving, "f").concat(name));
171
- }
172
- __classPrivateFieldGet(this, _Options_colorResolving, "f").push(name);
173
- const contrastTo = styleColor.contrastTo();
174
- const notEqualTo = styleColor.notEqualTo();
175
- try {
176
- if (contrastTo) {
177
- const refColor = this.color(contrastTo)[0];
178
- if (refColor) {
179
- candidates = Color.sortByContrast(candidates, refColor);
180
- }
181
- }
182
- if (notEqualTo.length > 0) {
183
- const excluded = [];
184
- for (const ref of notEqualTo) {
185
- for (const color of this.color(ref)) {
186
- excluded.push(color);
187
- }
188
- }
189
- candidates = Color.filterNotEqualTo(candidates, excluded);
190
- }
191
- }
192
- finally {
193
- __classPrivateFieldGet(this, _Options_colorResolving, "f").pop();
194
- }
195
- // Skip shuffle when sorted by contrast to preserve the ordering
196
- const ordered = contrastTo
197
- ? candidates
198
- : __classPrivateFieldGet(this, _Options_prng, "f").shuffle(`${name}Color`, candidates);
199
- return ordered.slice(0, stops);
200
- }, _Options_get = function _Options_get(key) {
107
+ _Options_data = new WeakMap(), _Options_instances = new WeakSet(), _Options_dynamic = function _Options_dynamic(key) {
201
108
  return __classPrivateFieldGet(this, _Options_data, "f")[key];
202
- }, _Options_memo = function _Options_memo(key, compute) {
203
- if (key in __classPrivateFieldGet(this, _Options_result, "f")) {
204
- return __classPrivateFieldGet(this, _Options_result, "f")[key];
205
- }
206
- const value = compute();
207
- __classPrivateFieldGet(this, _Options_result, "f")[key] = value;
208
- return value;
209
- }, _Options_toArray = function _Options_toArray(value) {
109
+ }, _Options_asArray = function _Options_asArray(value) {
210
110
  if (value === undefined) {
211
111
  return [];
212
112
  }
@@ -29,9 +29,17 @@ interface RangeField {
29
29
  }
30
30
  export type FieldDescriptor = StringField | NumberField | BooleanField | EnumField | ColorField | RangeField;
31
31
  export type Descriptor = Record<string, FieldDescriptor>;
32
+ /**
33
+ * Builds a descriptor of every option a given style accepts. Tooling such as
34
+ * the editor uses the result to render form controls and validation hints
35
+ * without having to introspect the style itself.
36
+ */
32
37
  export declare class OptionsDescriptor {
33
38
  #private;
34
39
  constructor(style: Style);
40
+ /**
41
+ * Returns a deep clone of the descriptor, building it lazily on first call.
42
+ */
35
43
  toJSON(): Descriptor;
36
44
  }
37
45
  export {};
@@ -10,6 +10,11 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
12
  var _OptionsDescriptor_instances, _a, _OptionsDescriptor_rotateRange, _OptionsDescriptor_translateRange, _OptionsDescriptor_descriptor, _OptionsDescriptor_style, _OptionsDescriptor_build;
13
+ /**
14
+ * Builds a descriptor of every option a given style accepts. Tooling such as
15
+ * the editor uses the result to render form controls and validation hints
16
+ * without having to introspect the style itself.
17
+ */
13
18
  export class OptionsDescriptor {
14
19
  constructor(style) {
15
20
  _OptionsDescriptor_instances.add(this);
@@ -17,6 +22,9 @@ export class OptionsDescriptor {
17
22
  _OptionsDescriptor_style.set(this, void 0);
18
23
  __classPrivateFieldSet(this, _OptionsDescriptor_style, style, "f");
19
24
  }
25
+ /**
26
+ * Returns a deep clone of the descriptor, building it lazily on first call.
27
+ */
20
28
  toJSON() {
21
29
  __classPrivateFieldSet(this, _OptionsDescriptor_descriptor, __classPrivateFieldGet(this, _OptionsDescriptor_descriptor, "f") ?? __classPrivateFieldGet(this, _OptionsDescriptor_instances, "m", _OptionsDescriptor_build).call(this), "f");
22
30
  return structuredClone(__classPrivateFieldGet(this, _OptionsDescriptor_descriptor, "f"));
@@ -25,7 +33,7 @@ export class OptionsDescriptor {
25
33
  _a = OptionsDescriptor, _OptionsDescriptor_descriptor = new WeakMap(), _OptionsDescriptor_style = new WeakMap(), _OptionsDescriptor_instances = new WeakSet(), _OptionsDescriptor_build = function _OptionsDescriptor_build() {
26
34
  const result = {
27
35
  seed: { type: 'string' },
28
- size: { type: 'number', min: 1 },
36
+ size: { type: 'number', min: 1, max: 4096 },
29
37
  idRandomization: { type: 'boolean' },
30
38
  title: { type: 'string' },
31
39
  flip: {
@@ -35,13 +43,16 @@ _a = OptionsDescriptor, _OptionsDescriptor_descriptor = new WeakMap(), _OptionsD
35
43
  },
36
44
  fontFamily: { type: 'string', list: true },
37
45
  fontWeight: { type: 'number', min: 1, max: 1000, list: true },
38
- scale: { type: 'range', min: 0 },
46
+ scale: { type: 'range', min: 0, max: 10 },
39
47
  borderRadius: { type: 'range', min: 0, max: 50 },
40
48
  rotate: __classPrivateFieldGet(_a, _a, "f", _OptionsDescriptor_rotateRange),
41
49
  translateX: __classPrivateFieldGet(_a, _a, "f", _OptionsDescriptor_translateRange),
42
50
  translateY: __classPrivateFieldGet(_a, _a, "f", _OptionsDescriptor_translateRange),
43
51
  };
44
52
  for (const [name, component] of __classPrivateFieldGet(this, _OptionsDescriptor_style, "f").components()) {
53
+ if (component.extendsName() !== undefined) {
54
+ continue;
55
+ }
45
56
  const variants = Array.from(component.variants().keys()).sort();
46
57
  result[`${name}Variant`] = {
47
58
  type: 'enum',
@@ -50,9 +61,6 @@ _a = OptionsDescriptor, _OptionsDescriptor_descriptor = new WeakMap(), _OptionsD
50
61
  weighted: true,
51
62
  };
52
63
  result[`${name}Probability`] = { type: 'number', min: 0, max: 100 };
53
- result[`${name}Rotate`] = __classPrivateFieldGet(_a, _a, "f", _OptionsDescriptor_rotateRange);
54
- result[`${name}TranslateX`] = __classPrivateFieldGet(_a, _a, "f", _OptionsDescriptor_translateRange);
55
- result[`${name}TranslateY`] = __classPrivateFieldGet(_a, _a, "f", _OptionsDescriptor_translateRange);
56
64
  }
57
65
  for (const name of [...__classPrivateFieldGet(this, _OptionsDescriptor_style, "f").colors().keys(), 'background']) {
58
66
  result[`${name}Color`] = { type: 'color', list: true };
@@ -67,4 +75,4 @@ _a = OptionsDescriptor, _OptionsDescriptor_descriptor = new WeakMap(), _OptionsD
67
75
  return result;
68
76
  };
69
77
  _OptionsDescriptor_rotateRange = { value: { type: 'range', min: -360, max: 360 } };
70
- _OptionsDescriptor_translateRange = { value: { type: 'range', min: -100, max: 100 } };
78
+ _OptionsDescriptor_translateRange = { value: { type: 'range', min: -1000, max: 1000 } };
@@ -1,4 +1,18 @@
1
+ /**
2
+ * FNV-1a 32-bit hash.
3
+ *
4
+ * Offset basis: 0x811c9dc5, prime: 0x01000193.
5
+ *
6
+ * @see https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
7
+ */
1
8
  export declare class Fnv1a {
9
+ /**
10
+ * Returns the unsigned 32-bit FNV-1a hash of `input`. UTF-16 code units
11
+ * are hashed directly so the result is identical across language ports.
12
+ */
2
13
  static hash(input: string): number;
14
+ /**
15
+ * Returns the FNV-1a hash of `input` as an 8-character lowercase hex string.
16
+ */
3
17
  static hex(input: string): string;
4
18
  }
package/lib/Prng/Fnv1a.js CHANGED
@@ -1,7 +1,15 @@
1
- // FNV-1a 32-bit hash.
2
- // Offset basis: 0x811c9dc5, prime: 0x01000193.
3
- // https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
1
+ /**
2
+ * FNV-1a 32-bit hash.
3
+ *
4
+ * Offset basis: 0x811c9dc5, prime: 0x01000193.
5
+ *
6
+ * @see https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
7
+ */
4
8
  export class Fnv1a {
9
+ /**
10
+ * Returns the unsigned 32-bit FNV-1a hash of `input`. UTF-16 code units
11
+ * are hashed directly so the result is identical across language ports.
12
+ */
5
13
  static hash(input) {
6
14
  let hash = 0x811c9dc5;
7
15
  for (let i = 0; i < input.length; i++) {
@@ -10,6 +18,9 @@ export class Fnv1a {
10
18
  }
11
19
  return hash >>> 0;
12
20
  }
21
+ /**
22
+ * Returns the FNV-1a hash of `input` as an 8-character lowercase hex string.
23
+ */
13
24
  static hex(input) {
14
25
  return Fnv1a.hash(input).toString(16).padStart(8, '0');
15
26
  }