vanilla-jui 1.7.1 → 1.7.2

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.
@@ -3,7 +3,7 @@ import { insert, jsx } from 'vanilla-signal';
3
3
  import { type DOMReference, resolveElement } from '../utilities/dom.ts';
4
4
  import { randomId } from '../utilities/id.ts';
5
5
  import { timer } from '../utilities/timer.ts';
6
- import { type ResolveSchema, resolveProps } from '../utilities/types.ts';
6
+ import { type ConfigSchema, resolveConfig } from '../utilities/config.ts';
7
7
 
8
8
  type ParabolaDirection =
9
9
  | 'center'
@@ -81,10 +81,7 @@ const PARABOLA_PROPS_SCHEMA = {
81
81
  ball: {
82
82
  default: DEFAULT_BALL,
83
83
  type: 'plainObject',
84
- normalize: (value: unknown) => ({
85
- ...DEFAULT_BALL,
86
- ...(value && typeof value === 'object' ? value : {}),
87
- }),
84
+ merge: 'shallow',
88
85
  shape: {
89
86
  color: 'string',
90
87
  size: 'string',
@@ -92,11 +89,8 @@ const PARABOLA_PROPS_SCHEMA = {
92
89
  },
93
90
  className: {
94
91
  default: DEFAULT_CLASS_NAMES,
95
- type: 'object',
96
- normalize: (value: unknown) => ({
97
- ...DEFAULT_CLASS_NAMES,
98
- ...(value && typeof value === 'object' ? value : {}),
99
- }),
92
+ type: 'plainObject',
93
+ merge: 'shallow',
100
94
  },
101
95
  from: { default: null, ...ELEMENT_REF_RULE },
102
96
  to: { default: null, ...ELEMENT_REF_RULE },
@@ -108,10 +102,10 @@ const PARABOLA_PROPS_SCHEMA = {
108
102
  showDelay: { default: 0, type: 'number' },
109
103
  onShow: { default: null, types: ['function', 'null'] },
110
104
  onHidden: { default: null, types: ['function', 'null'] },
111
- } satisfies ResolveSchema<ParabolaProps>;
105
+ } satisfies ConfigSchema<ParabolaProps>;
112
106
 
113
107
  function normalizeProps(input: ParabolaProps): ResolvedParabolaProps {
114
- const props = resolveProps(input, PARABOLA_PROPS_SCHEMA, 'Parabola.props');
108
+ const props = resolveConfig(input, PARABOLA_PROPS_SCHEMA, 'Parabola.props');
115
109
  return {
116
110
  ball: props.ball as ParabolaBallProps,
117
111
  className: props.className as ParabolaClassNames,
@@ -1,7 +1,7 @@
1
1
  import { type ElementProps, jsx } from 'vanilla-signal';
2
2
 
3
3
  import { asRenderable, type RenderableContent } from '../utilities/dom.ts';
4
- import { type ResolveSchema, resolveProps } from '../utilities/types.ts';
4
+ import { type ConfigSchema, resolveConfig } from '../utilities/config.ts';
5
5
 
6
6
  export interface PopupProps extends Record<string, unknown> {
7
7
  className?: string;
@@ -28,10 +28,10 @@ const POPUP_PROPS_SCHEMA = {
28
28
  default: '',
29
29
  type: 'renderable',
30
30
  },
31
- } satisfies ResolveSchema<PopupProps>;
31
+ } satisfies ConfigSchema<PopupProps>;
32
32
 
33
33
  function normalizeProps(input: PopupProps): ResolvedPopupProps {
34
- const props = resolveProps(input, POPUP_PROPS_SCHEMA, 'Popup');
34
+ const props = resolveConfig(input, POPUP_PROPS_SCHEMA, 'Popup');
35
35
 
36
36
  return {
37
37
  className: props.className as string,
@@ -1,7 +1,7 @@
1
1
  import { createDeepStore, flushSync } from 'vanilla-signal';
2
2
  import { randomId } from '../utilities/id.ts';
3
3
  import { type DOMReference, all, requireContainer } from '../utilities/dom.ts';
4
- import { type ResolveSchema, resolveProps } from '../utilities/types.ts';
4
+ import { type ConfigSchema, resolveConfig } from '../utilities/config.ts';
5
5
 
6
6
  type StickyOverflow = 'destroy' | 'ignore';
7
7
 
@@ -91,10 +91,10 @@ const STICKY_PROPS_SCHEMA = {
91
91
  },
92
92
  reactive: { default: false, type: 'boolean' },
93
93
  onReBuild: { default: null, types: ['function', 'null'] },
94
- } satisfies ResolveSchema<StickyProps>;
94
+ } satisfies ConfigSchema<StickyProps>;
95
95
 
96
96
  function normalizeProps(input: StickyProps): ResolvedStickyProps {
97
- const props = resolveProps(input, STICKY_PROPS_SCHEMA, 'Sticky.props');
97
+ const props = resolveConfig(input, STICKY_PROPS_SCHEMA, 'Sticky.props');
98
98
  return {
99
99
  target: props.target as DOMReference,
100
100
  parent: props.parent as DOMReference,
@@ -11,6 +11,8 @@ import { translate } from '../utilities/locale.ts';
11
11
  import { all, joinClasses } from '../utilities/dom.ts';
12
12
  import { createEventManager } from '../utilities/events.ts';
13
13
  import { isPlainObject } from '../utilities/object.ts';
14
+ import { type ConfigSchema, resolveConfig } from '../utilities/config.ts';
15
+ import { mergeShallowConfig } from '../utilities/merge.ts';
14
16
 
15
17
  export type ThemeConfigKey = 'mode' | 'theme' | 'radius' | 'shadow' | 'font';
16
18
 
@@ -101,16 +103,26 @@ const THEME_CLASS_PREFIX: Record<Exclude<ThemeConfigKey, 'mode'>, string> = {
101
103
  font: 'j-font-',
102
104
  };
103
105
 
104
- function mergeClassNames(className?: ThemeClassNameConfig): ThemeClassNames {
105
- return { ...DEFAULT_CLASS_NAMES, ...className };
106
- }
106
+ const THEME_OPTIONS_SCHEMA = {
107
+ mode: { default: DEFAULT_OPTIONS.mode, type: 'string' },
108
+ theme: { default: DEFAULT_OPTIONS.theme, type: 'string' },
109
+ radius: { default: DEFAULT_OPTIONS.radius, type: 'string' },
110
+ shadow: { default: DEFAULT_OPTIONS.shadow, type: 'string' },
111
+ font: { default: DEFAULT_OPTIONS.font, type: 'string' },
112
+ key: { default: DEFAULT_OPTIONS.key, type: 'string' },
113
+ className: {
114
+ default: DEFAULT_CLASS_NAMES,
115
+ type: 'plainObject',
116
+ merge: 'shallow',
117
+ },
118
+ } satisfies ConfigSchema<ThemeOptions>;
107
119
 
108
120
  function normalizeOptions(options: ThemeOptions = {}): ThemeResolvedOptions {
109
- return {
110
- ...DEFAULT_OPTIONS,
111
- ...options,
112
- className: mergeClassNames(options.className),
113
- };
121
+ return resolveConfig(
122
+ options,
123
+ THEME_OPTIONS_SCHEMA,
124
+ 'Theme.options'
125
+ ) as unknown as ThemeResolvedOptions;
114
126
  }
115
127
 
116
128
  function isThemeConfigKey(value: string | undefined): value is ThemeConfigKey {
@@ -340,14 +352,17 @@ export function createTheme(options: ThemeOptions = {}): ThemeInstance {
340
352
  return panel;
341
353
  };
342
354
  const setConfig = (newConfig: ThemeOptions): void => {
355
+ const config = normalizeOptions({
356
+ ...props,
357
+ ...newConfig,
358
+ className: mergeShallowConfig(
359
+ props.className,
360
+ newConfig.className ?? {}
361
+ ) as ThemeClassNames,
362
+ });
343
363
  runtime.configVersion += 1;
344
364
  flushSync(() => {
345
- Object.assign(props, newConfig, {
346
- className: mergeClassNames({
347
- ...props.className,
348
- ...newConfig.className,
349
- }),
350
- });
365
+ Object.assign(props, config);
351
366
  });
352
367
  saveConfig();
353
368
  };
@@ -12,6 +12,7 @@ import { createLoading } from '../primitives/loading.ts';
12
12
  import { joinClasses, q } from '../utilities/dom.ts';
13
13
  import { listen } from '../utilities/events.ts';
14
14
  import { randomId } from '../utilities/id.ts';
15
+ import { mergeShallowConfig } from '../utilities/merge.ts';
15
16
  import { timer } from '../utilities/timer.ts';
16
17
  import { validateParam } from '../utilities/types.ts';
17
18
 
@@ -98,14 +99,6 @@ const operations = new Map<HTMLElement, number>();
98
99
  const singletonToasts = new Map<'show' | 'confirm', HTMLElement>();
99
100
  let classNames = DEFAULT_CLASS_NAMES;
100
101
 
101
- function mergeClassNames(value?: ToastClassNameConfig): ToastClassNames {
102
- return { ...DEFAULT_CLASS_NAMES, ...value };
103
- }
104
-
105
- function resolveClassNames(options?: ToastClassNameOptions): ToastClassNames {
106
- return mergeClassNames({ ...classNames, ...options?.className });
107
- }
108
-
109
102
  function addToastDisposer(element: HTMLElement, dispose: () => void): void {
110
103
  const current = disposers.get(element);
111
104
  disposers.set(element, () => {
@@ -378,7 +371,10 @@ function show(message = '', options: ToastOptions = {}): HTMLElement {
378
371
  validateParam('duration', duration, TOAST_DURATION_RULE, 'Toast.show');
379
372
  validateParam('theme', theme, TOAST_THEME_RULE, 'Toast.show');
380
373
 
381
- const names = resolveClassNames(options);
374
+ const names = mergeShallowConfig(
375
+ classNames,
376
+ options.className ?? {}
377
+ ) as ToastClassNames;
382
378
  const id = randomId();
383
379
  const iconElement = jsx('span', {
384
380
  className: names.icon,
@@ -426,7 +422,10 @@ function lite(
426
422
  validateParam('message', message, 'string', 'Toast.lite');
427
423
  validateParam('duration', duration, LITE_DURATION_RULE, 'Toast.lite');
428
424
 
429
- const names = mergeClassNames({ ...classNames, ...className });
425
+ const names = mergeShallowConfig(
426
+ classNames,
427
+ className ?? {}
428
+ ) as ToastClassNames;
430
429
  const previous = q<HTMLElement>('[data-toast-lite]');
431
430
  if (previous) {
432
431
  cancelToastTimers(previous.dataset.toast || '');
@@ -457,7 +456,10 @@ function confirm(message = '', props: ToastConfirmProps = {}): HTMLElement {
457
456
  const theme = props.theme || 'info';
458
457
  validateParam('once', once, 'boolean', 'Toast.confirm');
459
458
  validateParam('theme', theme, TOAST_THEME_RULE, 'Toast.confirm');
460
- const names = resolveClassNames(props);
459
+ const names = mergeShallowConfig(
460
+ classNames,
461
+ props.className ?? {}
462
+ ) as ToastClassNames;
461
463
  const id = randomId();
462
464
  const element = jsx('div', {
463
465
  className: joinClasses(names.confirm, names[theme]),
@@ -526,7 +528,10 @@ export const Toast = {
526
528
  timers,
527
529
  disposers,
528
530
  configure(options: ToastClassNameOptions = {}): ToastClassNameOptions {
529
- classNames = mergeClassNames(options.className);
531
+ classNames = mergeShallowConfig(
532
+ DEFAULT_CLASS_NAMES,
533
+ options.className ?? {}
534
+ ) as ToastClassNames;
530
535
  return { className: classNames };
531
536
  },
532
537
  show,
@@ -1,7 +1,7 @@
1
1
  import { jsx } from 'vanilla-signal';
2
2
 
3
3
  import { type DOMReference, joinClasses } from '../utilities/dom.ts';
4
- import { type ResolveSchema, resolveProps } from '../utilities/types.ts';
4
+ import { type ConfigSchema, resolveConfig } from '../utilities/config.ts';
5
5
  import { createDrop } from './drop.ts';
6
6
 
7
7
  type DropInstance = ReturnType<typeof createDrop>;
@@ -102,20 +102,6 @@ const DEFAULT_CLASS_NAMES: TooltipClassNames = {
102
102
  },
103
103
  };
104
104
 
105
- function normalizeClassNames(value: unknown): TooltipClassNames {
106
- const input = value && typeof value === 'object' ? value : {};
107
- const ui =
108
- 'ui' in input && input.ui && typeof input.ui === 'object' ? input.ui : {};
109
- return {
110
- ...DEFAULT_CLASS_NAMES,
111
- ...input,
112
- ui: {
113
- ...DEFAULT_CLASS_NAMES.ui,
114
- ...ui,
115
- },
116
- };
117
- }
118
-
119
105
  const TOOLTIP_OPTIONS_SCHEMA = {
120
106
  name: { default: null, types: ['string', 'null'] },
121
107
  mode: { default: 'hover', type: 'string', enum: ['hover', 'click'] },
@@ -155,18 +141,18 @@ const TOOLTIP_OPTIONS_SCHEMA = {
155
141
  },
156
142
  className: {
157
143
  default: DEFAULT_CLASS_NAMES,
158
- type: 'object',
159
- normalize: normalizeClassNames,
144
+ type: 'plainObject',
145
+ merge: 'deep',
160
146
  },
161
147
  id: { default: null, types: ['string', 'null'] },
162
148
  delay: { default: 100, types: ['number', 'object'] },
163
149
  hoverIntent: { default: true, type: 'boolean' },
164
150
  onShown: { default: null, types: ['function', 'null'] },
165
151
  onHidden: { default: null, types: ['function', 'null'] },
166
- } satisfies ResolveSchema<TooltipProps>;
152
+ } satisfies ConfigSchema<TooltipProps>;
167
153
 
168
154
  function normalizeProps(input: TooltipProps): ResolvedTooltipProps {
169
- const props = resolveProps(input, TOOLTIP_OPTIONS_SCHEMA, 'Tooltip.props');
155
+ const props = resolveConfig(input, TOOLTIP_OPTIONS_SCHEMA, 'Tooltip.props');
170
156
  return {
171
157
  name: props.name as string | null,
172
158
  mode: props.mode as DropMode,
@@ -0,0 +1,158 @@
1
+ import { type ParamRule, type ParamRuleInput, validateParam } from './types.ts';
2
+ import {
3
+ type MergeStrategy,
4
+ cloneConfigValue,
5
+ mergeConfigValue,
6
+ } from './merge.ts';
7
+ import { isPlainObject } from './object.ts';
8
+
9
+ type LooseRecord = Record<string, unknown>;
10
+ type ConfigTypeRule = string | readonly string[];
11
+
12
+ export interface ConfigNormalizeContext<
13
+ TInput extends LooseRecord = LooseRecord,
14
+ > {
15
+ key: string;
16
+ path: string;
17
+ input: TInput;
18
+ options: LooseRecord;
19
+ schema: ConfigSchema<TInput>;
20
+ }
21
+
22
+ export interface ConfigRule<
23
+ TInput extends LooseRecord = LooseRecord,
24
+ > extends Omit<ParamRule<TInput>, 'normalize' | 'shape'> {
25
+ defaultFactory?: () => unknown;
26
+ merge?: MergeStrategy;
27
+ schema?: ConfigSchema;
28
+ normalize?: (
29
+ value: unknown,
30
+ context: ConfigNormalizeContext<TInput>
31
+ ) => unknown;
32
+ }
33
+
34
+ export type ConfigRuleInput<TInput extends LooseRecord = LooseRecord> =
35
+ | ConfigTypeRule
36
+ | ConfigRule<TInput>;
37
+
38
+ export type ConfigSchema<TInput extends LooseRecord = LooseRecord> = Record<
39
+ string,
40
+ ConfigRuleInput<TInput>
41
+ >;
42
+
43
+ export type ResolvedConfig<TSchema extends object> = LooseRecord & {
44
+ [Key in keyof TSchema]: unknown;
45
+ };
46
+
47
+ function normalizeConfigRule<TInput extends LooseRecord>(
48
+ rule: ConfigRuleInput<TInput> = {}
49
+ ): ConfigRule<TInput> {
50
+ if (typeof rule === 'string' || Array.isArray(rule)) return { type: rule };
51
+ if (!rule || typeof rule !== 'object') return {};
52
+ return rule as ConfigRule<TInput>;
53
+ }
54
+
55
+ function resolveConfigDefault<TInput extends LooseRecord>(
56
+ rule: ConfigRule<TInput>
57
+ ): unknown {
58
+ if (typeof rule.defaultFactory === 'function') {
59
+ return cloneConfigValue(rule.defaultFactory());
60
+ }
61
+ if (Object.hasOwn(rule, 'default')) {
62
+ return cloneConfigValue(rule.default);
63
+ }
64
+ return undefined;
65
+ }
66
+
67
+ function isInputMissing(source: LooseRecord, key: string): boolean {
68
+ return !Object.hasOwn(source, key) || source[key] === undefined;
69
+ }
70
+
71
+ function resolveConfigValue<TInput extends LooseRecord>(
72
+ key: string,
73
+ rule: ConfigRule<TInput>,
74
+ source: TInput,
75
+ namespace: string
76
+ ): unknown {
77
+ const path = namespace ? `${namespace}.${key}` : key;
78
+ const defaultValue = resolveConfigDefault(rule);
79
+ const value = isInputMissing(source, key)
80
+ ? defaultValue
81
+ : mergeConfigValue(defaultValue, source[key], rule.merge, { key, path });
82
+
83
+ return rule.schema && (value === undefined || isPlainObject(value))
84
+ ? resolveConfig(value as LooseRecord | undefined, rule.schema, path)
85
+ : value;
86
+ }
87
+
88
+ function validateConfigValue<TInput extends LooseRecord>(
89
+ key: string,
90
+ value: unknown,
91
+ rule: ConfigRule<TInput>,
92
+ namespace: string
93
+ ): void {
94
+ const validationRule: ParamRuleInput<TInput> = rule as ParamRule<TInput>;
95
+ validateParam(key, value, validationRule, namespace);
96
+
97
+ if (!rule.schema || !isPlainObject(value)) return;
98
+
99
+ const childNamespace = namespace ? `${namespace}.${key}` : key;
100
+ const valueRecord = value as LooseRecord;
101
+ for (const [childKey, childRule] of Object.entries(rule.schema)) {
102
+ validateConfigValue(
103
+ childKey,
104
+ valueRecord[childKey],
105
+ normalizeConfigRule(childRule),
106
+ childNamespace
107
+ );
108
+ }
109
+ }
110
+
111
+ export function resolveConfig<
112
+ TInput extends LooseRecord,
113
+ TSchema extends ConfigSchema<TInput>,
114
+ >(
115
+ input: TInput | null | undefined = {} as TInput,
116
+ schema: TSchema = {} as TSchema,
117
+ namespace = 'Config'
118
+ ): ResolvedConfig<TSchema> {
119
+ const source = input == null ? {} : input;
120
+ if (typeof source !== 'object' || Array.isArray(source)) {
121
+ throw new Error(`${namespace} expects object.`);
122
+ }
123
+
124
+ const sourceRecord = source as TInput;
125
+ const resolved: LooseRecord = {};
126
+ const entries = Object.entries(schema || {}) as Array<
127
+ [string, ConfigRuleInput<TInput>]
128
+ >;
129
+
130
+ for (const [key, rawRule] of entries) {
131
+ const rule = normalizeConfigRule<TInput>(rawRule);
132
+ resolved[key] = resolveConfigValue(key, rule, sourceRecord, namespace);
133
+ }
134
+
135
+ for (const [key, rawRule] of entries) {
136
+ const rule = normalizeConfigRule<TInput>(rawRule);
137
+ if (typeof rule.normalize === 'function') {
138
+ resolved[key] = rule.normalize(resolved[key], {
139
+ key,
140
+ path: namespace ? `${namespace}.${key}` : key,
141
+ input: sourceRecord,
142
+ options: resolved,
143
+ schema,
144
+ });
145
+ }
146
+ }
147
+
148
+ for (const [key, rule] of entries) {
149
+ validateConfigValue(
150
+ key,
151
+ resolved[key],
152
+ normalizeConfigRule<TInput>(rule),
153
+ namespace
154
+ );
155
+ }
156
+
157
+ return resolved as ResolvedConfig<TSchema>;
158
+ }
@@ -73,113 +73,113 @@ type QueryParamValue =
73
73
  */
74
74
  type QueryParams = Record<string, QueryParamValue>;
75
75
 
76
- const SHA256_K = new Uint32Array([
77
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
78
- 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
79
- 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
80
- 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
81
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
82
- 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
83
- 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
84
- 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
85
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
86
- 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
87
- 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
88
- ]);
89
-
90
- const SHA256_INITIAL = new Uint32Array([
91
- 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,
92
- 0x1f83d9ab, 0x5be0cd19,
93
- ]);
94
-
95
- function rotateRight(value: number, bits: number): number {
96
- return (value >>> bits) | (value << (32 - bits));
97
- }
98
-
99
- function sha256Fallback(input: Uint8Array): Uint8Array {
100
- const message = new Uint8Array(Math.ceil((input.length + 9) / 64) * 64);
101
- message.set(input);
102
- message[input.length] = 0x80;
103
-
104
- const bitLength = BigInt(input.length) * 8n;
105
- for (let i = 0; i < 8; i += 1) {
106
- message[message.length - 1 - i] = Number(
107
- (bitLength >> BigInt(i * 8)) & 0xffn
108
- );
109
- }
110
-
111
- const hash = new Uint32Array(SHA256_INITIAL);
112
- const words = new Uint32Array(64);
113
-
114
- for (let offset = 0; offset < message.length; offset += 64) {
115
- for (let i = 0; i < 16; i += 1) {
116
- const index = offset + i * 4;
117
- words[i] =
118
- ((message[index] << 24) |
119
- (message[index + 1] << 16) |
120
- (message[index + 2] << 8) |
121
- message[index + 3]) >>>
122
- 0;
123
- }
124
-
125
- for (let i = 16; i < 64; i += 1) {
126
- const s0 =
127
- rotateRight(words[i - 15], 7) ^
128
- rotateRight(words[i - 15], 18) ^
129
- (words[i - 15] >>> 3);
130
- const s1 =
131
- rotateRight(words[i - 2], 17) ^
132
- rotateRight(words[i - 2], 19) ^
133
- (words[i - 2] >>> 10);
134
- words[i] = (words[i - 16] + s0 + words[i - 7] + s1) >>> 0;
135
- }
136
-
137
- let a = hash[0];
138
- let b = hash[1];
139
- let c = hash[2];
140
- let d = hash[3];
141
- let e = hash[4];
142
- let f = hash[5];
143
- let g = hash[6];
144
- let h = hash[7];
145
-
146
- for (let i = 0; i < 64; i += 1) {
147
- const s1 = rotateRight(e, 6) ^ rotateRight(e, 11) ^ rotateRight(e, 25);
148
- const ch = (e & f) ^ (~e & g);
149
- const temp1 = (h + s1 + ch + SHA256_K[i] + words[i]) >>> 0;
150
- const s0 = rotateRight(a, 2) ^ rotateRight(a, 13) ^ rotateRight(a, 22);
151
- const maj = (a & b) ^ (a & c) ^ (b & c);
152
- const temp2 = (s0 + maj) >>> 0;
153
-
154
- h = g;
155
- g = f;
156
- f = e;
157
- e = (d + temp1) >>> 0;
158
- d = c;
159
- c = b;
160
- b = a;
161
- a = (temp1 + temp2) >>> 0;
162
- }
163
-
164
- hash[0] = (hash[0] + a) >>> 0;
165
- hash[1] = (hash[1] + b) >>> 0;
166
- hash[2] = (hash[2] + c) >>> 0;
167
- hash[3] = (hash[3] + d) >>> 0;
168
- hash[4] = (hash[4] + e) >>> 0;
169
- hash[5] = (hash[5] + f) >>> 0;
170
- hash[6] = (hash[6] + g) >>> 0;
171
- hash[7] = (hash[7] + h) >>> 0;
172
- }
173
-
174
- const output = new Uint8Array(32);
175
- for (let i = 0; i < hash.length; i += 1) {
176
- output[i * 4] = hash[i] >>> 24;
177
- output[i * 4 + 1] = hash[i] >>> 16;
178
- output[i * 4 + 2] = hash[i] >>> 8;
179
- output[i * 4 + 3] = hash[i];
180
- }
181
- return output;
182
- }
76
+ // const SHA256_K = new Uint32Array([
77
+ // 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
78
+ // 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
79
+ // 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
80
+ // 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
81
+ // 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
82
+ // 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
83
+ // 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
84
+ // 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
85
+ // 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
86
+ // 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
87
+ // 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
88
+ // ]);
89
+
90
+ // const SHA256_INITIAL = new Uint32Array([
91
+ // 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,
92
+ // 0x1f83d9ab, 0x5be0cd19,
93
+ // ]);
94
+
95
+ // function rotateRight(value: number, bits: number): number {
96
+ // return (value >>> bits) | (value << (32 - bits));
97
+ // }
98
+
99
+ // function sha256Fallback(input: Uint8Array): Uint8Array {
100
+ // const message = new Uint8Array(Math.ceil((input.length + 9) / 64) * 64);
101
+ // message.set(input);
102
+ // message[input.length] = 0x80;
103
+
104
+ // const bitLength = BigInt(input.length) * 8n;
105
+ // for (let i = 0; i < 8; i += 1) {
106
+ // message[message.length - 1 - i] = Number(
107
+ // (bitLength >> BigInt(i * 8)) & 0xffn
108
+ // );
109
+ // }
110
+
111
+ // const hash = new Uint32Array(SHA256_INITIAL);
112
+ // const words = new Uint32Array(64);
113
+
114
+ // for (let offset = 0; offset < message.length; offset += 64) {
115
+ // for (let i = 0; i < 16; i += 1) {
116
+ // const index = offset + i * 4;
117
+ // words[i] =
118
+ // ((message[index] << 24) |
119
+ // (message[index + 1] << 16) |
120
+ // (message[index + 2] << 8) |
121
+ // message[index + 3]) >>>
122
+ // 0;
123
+ // }
124
+
125
+ // for (let i = 16; i < 64; i += 1) {
126
+ // const s0 =
127
+ // rotateRight(words[i - 15], 7) ^
128
+ // rotateRight(words[i - 15], 18) ^
129
+ // (words[i - 15] >>> 3);
130
+ // const s1 =
131
+ // rotateRight(words[i - 2], 17) ^
132
+ // rotateRight(words[i - 2], 19) ^
133
+ // (words[i - 2] >>> 10);
134
+ // words[i] = (words[i - 16] + s0 + words[i - 7] + s1) >>> 0;
135
+ // }
136
+
137
+ // let a = hash[0];
138
+ // let b = hash[1];
139
+ // let c = hash[2];
140
+ // let d = hash[3];
141
+ // let e = hash[4];
142
+ // let f = hash[5];
143
+ // let g = hash[6];
144
+ // let h = hash[7];
145
+
146
+ // for (let i = 0; i < 64; i += 1) {
147
+ // const s1 = rotateRight(e, 6) ^ rotateRight(e, 11) ^ rotateRight(e, 25);
148
+ // const ch = (e & f) ^ (~e & g);
149
+ // const temp1 = (h + s1 + ch + SHA256_K[i] + words[i]) >>> 0;
150
+ // const s0 = rotateRight(a, 2) ^ rotateRight(a, 13) ^ rotateRight(a, 22);
151
+ // const maj = (a & b) ^ (a & c) ^ (b & c);
152
+ // const temp2 = (s0 + maj) >>> 0;
153
+
154
+ // h = g;
155
+ // g = f;
156
+ // f = e;
157
+ // e = (d + temp1) >>> 0;
158
+ // d = c;
159
+ // c = b;
160
+ // b = a;
161
+ // a = (temp1 + temp2) >>> 0;
162
+ // }
163
+
164
+ // hash[0] = (hash[0] + a) >>> 0;
165
+ // hash[1] = (hash[1] + b) >>> 0;
166
+ // hash[2] = (hash[2] + c) >>> 0;
167
+ // hash[3] = (hash[3] + d) >>> 0;
168
+ // hash[4] = (hash[4] + e) >>> 0;
169
+ // hash[5] = (hash[5] + f) >>> 0;
170
+ // hash[6] = (hash[6] + g) >>> 0;
171
+ // hash[7] = (hash[7] + h) >>> 0;
172
+ // }
173
+
174
+ // const output = new Uint8Array(32);
175
+ // for (let i = 0; i < hash.length; i += 1) {
176
+ // output[i * 4] = hash[i] >>> 24;
177
+ // output[i * 4 + 1] = hash[i] >>> 16;
178
+ // output[i * 4 + 2] = hash[i] >>> 8;
179
+ // output[i * 4 + 3] = hash[i];
180
+ // }
181
+ // return output;
182
+ // }
183
183
 
184
184
  async function sha256(input: Uint8Array): Promise<Uint8Array> {
185
185
  const subtle = globalThis.crypto?.subtle;
@@ -188,7 +188,8 @@ async function sha256(input: Uint8Array): Promise<Uint8Array> {
188
188
  new Uint8Array(source).set(input);
189
189
  return new Uint8Array(await subtle.digest('SHA-256', source));
190
190
  }
191
- return sha256Fallback(input);
191
+ // return sha256Fallback(input);
192
+ throw new Error('hashQueryParams only works in secure context.');
192
193
  }
193
194
 
194
195
  /**