Skip to content

Commit

Permalink
Add @discoveryjs/discovery/utils export
Browse files Browse the repository at this point in the history
  • Loading branch information
lahmatiy committed Oct 29, 2024
1 parent 8201c9c commit 241142b
Show file tree
Hide file tree
Showing 20 changed files with 82 additions and 91 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## next

- Added `@discoveryjs/discovery/utils` export
- Renamed `Widget` class into `ViewModel`
- Modified `PageRenderer#define()` and `ViewRenderer#define()` to allow specifying all options with a single config parameter:
```js
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
"discovery-dev": "./src/lib.js",
"default": "./lib/lib.js"
},
"./utils": {
"discovery-dev": "./src/core/utils/index.js",
"default": "./lib/core/utils/index.js"
},
"./dist/*": "./dist/*",
"./lib/*": "./lib/*",
"./src/*": {
Expand Down
4 changes: 2 additions & 2 deletions src/core/utils/base64.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ export function encodeBytes(input: string | number[] | Uint8Array): Uint8Array {
}

export function decode(input: string): string {
return decoder.decode(decodeBase64Bytes(input));
return decoder.decode(decodeBytes(input));
}

export function decodeBase64Bytes(input: string): Uint8Array {
export function decodeBytes(input: string): Uint8Array {
let inputSize = input.length;

// ignore trailing "=" (padding)
Expand Down
2 changes: 1 addition & 1 deletion src/core/utils/compare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export function equal(a: any, b: any, compare = Object.is) {
return true;
}

if (!a || typeof a !== 'object' || !b || typeof b !== 'object') {
if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) {
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/utils/container-styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { InitValue, resolveDarkmodeValue } from '../darkmode.js';

type Styles = Record<string, string>;
type SavedStyles = Record<string, [string, string]>;
type ApplyContainerStylesOptions = {
export type ApplyContainerStylesOptions = {
darkmode?: InitValue,
darkmodePersistent?: boolean;
};
Expand Down
6 changes: 3 additions & 3 deletions src/core/utils/debounce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
* Adopted for Discovery.js project
*/

type Options = {
export type DebounceOptions = {
wait: number;
maxWait?: number;
leading?: boolean;
}
type DebounceMethods<R> = {
export type DebounceMethods<R> = {
cancel(): void;
flush(): R;
pending(): boolean;
Expand Down Expand Up @@ -85,7 +85,7 @@ export function debounce<
T extends (...args: A) => R,
A extends any[],
R
>(func: T, options?: Options | number): T & DebounceMethods<R> {
>(func: T, options?: DebounceOptions | number): T & DebounceMethods<R> {
if (typeof func !== 'function') {
throw new TypeError('Expected a function');
}
Expand Down
13 changes: 6 additions & 7 deletions src/core/utils/dom.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
/* eslint-env browser */
import { hasOwn } from './object-utils.js';

type EventHandler<Element, Event> = (this: Element, evt: Event) => void;
type Attrs<TagName extends keyof HTMLElementTagNameMap> = {
[key in keyof HTMLElementEventMap as `on${key}`]?: EventHandler<
HTMLElementTagNameMap[TagName],
HTMLElementEventMap[key]
>;
export type CreateElementAttrs<TagName extends keyof HTMLElementTagNameMap> = {
[key in keyof HTMLElementEventMap as `on${key}`]?: (
this: HTMLElementTagNameMap[TagName],
evt: HTMLElementEventMap[key]
) => void;
} & {
[key: string]: any | undefined; // TODO: replace "any" with "string"
};

export function createElement<TagName extends keyof HTMLElementTagNameMap>(
tag: TagName,
attrs?: Attrs<TagName> | string | null,
attrs?: CreateElementAttrs<TagName> | string | null,
children?: (Node | string)[] | string
) {
const el = document.createElement(tag);
Expand Down
41 changes: 0 additions & 41 deletions src/core/utils/index.js

This file was deleted.

26 changes: 26 additions & 0 deletions src/core/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export * as base64 from './base64.js';
export { equal, deepEqual } from './compare.js';
export type { ApplyContainerStylesOptions } from './container-styles.js';
export { applyContainerStyles, rollbackContainerStyles } from './container-styles.js';
export { copyText } from './copy-text.js';
export { debounce } from './debounce.js';
export type { CreateElementAttrs } from './dom.js';
export { createElement, createFragment, createText, isDocumentFragment, passiveCaptureOptions, passiveSupported } from './dom.js';
export { randomId } from './id.js';
export { escapeHtml, numDelim } from './html.js';
export type { InjectStyle, InjectInlineStyle, InjectLinkStyle } from './inject-styles.js';
export { injectStyles } from './inject-styles.js';
export type { TypedArray } from './is-type.js';
export { isTypedArray, isArray, isSet, isRegExp } from './is-type.js';
export { jsonStringifyAsJavaScript, jsonStringifyInfo } from './json.js';
export { getBoundingRect, getOffsetParent, getOverflowParent, getPageOffset, getViewportRect } from './layout.js';
export type * from './load-data.js';
export * from './load-data.js';
export { objectToString, hasOwn } from './object-utils.js';
export { match, matchAll } from './pattern.js';
export { localStorageEntry, sessionStorageEntry } from './persistent.js';
export { pointerXY } from './pointer.js';
export type * from './progressbar.js';
export { Progressbar } from './progressbar.js';
export { safeFilterRx } from './safe-filter-rx.js';
export { ContentRect } from './size.js';
8 changes: 4 additions & 4 deletions src/core/utils/inject-styles.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { createElement } from './dom.js';

export type Style = string | InlineStyle | LinkStyle;
export type InlineStyle = {
export type InjectStyle = string | InjectInlineStyle | InjectLinkStyle;
export type InjectInlineStyle = {
type: 'style' | 'inline';
content: string;
media?: string;
};
export type LinkStyle = {
export type InjectLinkStyle = {
type: 'link' | 'external';
href: string;
media?: string;
};

export async function injectStyles(el: HTMLElement | ShadowRoot, styles?: Style[]) {
export async function injectStyles(el: HTMLElement | ShadowRoot, styles?: InjectStyle[]) {
const foucFix = createElement('style', null, ':host{display:none}');
const awaitingStyles = new Set<Promise<void>>();

Expand Down
2 changes: 1 addition & 1 deletion src/core/utils/is-type.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { objectToString } from './object-utils.js';

type TypedArray =
export type TypedArray =
| Uint8Array
| Uint8ClampedArray
| Uint16Array
Expand Down
6 changes: 3 additions & 3 deletions src/core/utils/layout.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-env browser */
const { documentElement } = document;
const standartsMode = document.compatMode === 'CSS1Compat';
const standardsMode = document.compatMode === 'CSS1Compat';

export function getOffsetParent(node: HTMLElement) {
let offsetParent = node.offsetParent as HTMLElement;
Expand Down Expand Up @@ -42,7 +42,7 @@ export function getPageOffset(element: HTMLElement | null = null) {
left = -rect.left;
} else {
// offset relative to page
if (standartsMode) {
if (standardsMode) {
top = window.pageYOffset || documentElement.scrollTop;
left = window.pageXOffset || documentElement.scrollLeft;
} else {
Expand Down Expand Up @@ -90,7 +90,7 @@ export function getViewportRect(
element: HTMLElement | Window,
relElement: HTMLElement | null = null
) {
const topViewport = standartsMode ? document.documentElement : document.body;
const topViewport = standardsMode ? document.documentElement : document.body;
let { top, left } = element === topViewport && !relElement
? getPageOffset()
: getBoundingRect(element, relElement);
Expand Down
2 changes: 1 addition & 1 deletion src/core/utils/pattern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function matchWithString(str: string, pattern: string, lastIndex: number) {
return offset !== -1 ? { offset, length: pattern.length } : null;
};

export function has(text: string, pattern: RegExp | string | null, ignoreCase = false) {
export function match(text: string, pattern: RegExp | string | null, ignoreCase = false) {
if (isRegExp(pattern)) {
return ignoreCase && !pattern.ignoreCase
? new RegExp(pattern, pattern.flags + 'i').test(text)
Expand Down
10 changes: 5 additions & 5 deletions src/core/utils/persistent.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { Emitter } from '../emitter.js';

export type StorageType = 'localStorage' | 'sessionStorage';
export type StorageMap = Map<string, PersistentKey> & {
storage: Storage | null;
getOrCreate: PersistentKeyGetOrCreate;
};
export type PersistentValue = string | null;
export type PersistentKey = {
readonly value: PersistentValue,
Expand All @@ -15,11 +19,7 @@ export type PersistentKeyEvents = {
change: [value: PersistentValue];
foo: [];
}
export type StorageMap = Map<string, PersistentKey> & {
storage: Storage | null;
getOrCreate: GetOrCreate;
};
export type GetOrCreate = ((key: string) => PersistentKey) & {
export type PersistentKeyGetOrCreate = ((key: string) => PersistentKey) & {
available: boolean;
};

Expand Down
28 changes: 14 additions & 14 deletions src/core/utils/progressbar.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import { Observer } from '../observer.js';
import { createElement } from './dom.js';

export type Stage = keyof typeof loadStages;
export type Timing = {
stage: Stage;
export type ProgressbarStage = keyof typeof loadStages;
export type ProgressbarTiming = {
stage: ProgressbarStage;
title: string;
duration: number;
};
export type OnTimingCallback = (timing: Timing) => void;
export type OnFinishCallback = (timings: Timing[] & { awaitRepaintPenaltyTime: number }) => void;
export type ProgressbarOnTimingCallback = (timing: ProgressbarTiming) => void;
export type ProgressbarOnFinishCallback = (timings: ProgressbarTiming[] & { awaitRepaintPenaltyTime: number }) => void;
export type ProgressbarOptions = Partial<{
onTiming: OnTimingCallback;
onFinish: OnFinishCallback;
onTiming: ProgressbarOnTimingCallback;
onFinish: ProgressbarOnFinishCallback;
domReady: Promise<any>;
}>;
export type ProgressbarState = {
stage: Stage;
stage: ProgressbarStage;
progress: {
done: boolean;
elapsed: number;
Expand Down Expand Up @@ -86,7 +86,7 @@ const letRepaintIfNeeded = async () => {
}
};

export function decodeStageProgress(stage: Stage, progress: ProgressbarState['progress'], step?: string) {
export function decodeStageProgress(stage: ProgressbarStage, progress: ProgressbarState['progress'], step?: string) {
const { value, title: stageTitle, duration } = loadStages[stage];
let progressValue = 0;
let progressText: string | null = null;
Expand Down Expand Up @@ -132,9 +132,9 @@ export class Progressbar extends Observer<ProgressbarState> {
awaitRepaintPenaltyTime: number;
finished: boolean;
awaitRepaint: number | null;
timings: Timing[];
onTiming: OnTimingCallback;
onFinish: OnFinishCallback;
timings: ProgressbarTiming[];
onTiming: ProgressbarOnTimingCallback;
onFinish: ProgressbarOnFinishCallback;
appearanceDelay: number;
domReady: Promise<any>;
el: HTMLElement;
Expand Down Expand Up @@ -163,8 +163,8 @@ export class Progressbar extends Observer<ProgressbarState> {
]);
}

recordTiming(stage: Stage, start: number, end = performance.now()) {
const entry: Timing = {
recordTiming(stage: ProgressbarStage, start: number, end = performance.now()) {
const entry: ProgressbarTiming = {
stage,
title: loadStages[stage].title,
duration: int(end - start)
Expand Down
2 changes: 2 additions & 0 deletions src/core/utils/size.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { Observer } from '../observer.js';
const resizeObserverSupported = typeof ResizeObserver === 'function';

export class ContentRect extends Observer<DOMRectReadOnly | null> {
static supported = resizeObserverSupported;

private el: HTMLElement | null;
private observer: ResizeObserver | null;

Expand Down
2 changes: 1 addition & 1 deletion src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import router from './extensions/router.js';
import embed from './extensions/embed-client.js';
import { buttons as navButtons } from './nav/index.js';
import { encoding as jsonxl } from './core/encodings/jsonxl.js';
import utils from './core/utils/index.js';
import * as utils from './core/utils/index.js';

export type * from './main/index.js';
export {
Expand Down
4 changes: 2 additions & 2 deletions src/main/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import type { SetDataProgressOptions, ViewModelEvents, ViewModelOptions } from './view-model.js';
import type { LoadDataBaseOptions, LoadDataResult } from '../core/utils/load-data.js';
import type { Style } from '../core/utils/inject-styles.js';
import type { InjectStyle } from '../core/utils/inject-styles.js';
import type { ProgressbarOptions } from '../core/utils/progressbar.js';
import type { UploadOptions } from '../extensions/upload.js';
import { hasOwn } from '../core/utils/object-utils.js';
Expand Down Expand Up @@ -222,7 +222,7 @@ export class App<
super.unloadData();
}

initDom(styles?: Style[]) {
initDom(styles?: InjectStyle[]) {
super.initDom(styles);

this.dom.container.append(
Expand Down
6 changes: 3 additions & 3 deletions src/main/view-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import type { ModelEvents, ModelOptions, PageParams, PageRef, SetDataOptions } from './model.js';
import type { Dataset } from '../core/utils/load-data.js';
import type { Style } from '../core/utils/inject-styles.js';
import type { InjectStyle } from '../core/utils/inject-styles.js';
import type { PageOptionName, PageOptions } from '../core/page.js';
import type { SingleViewConfig } from '../core/view.js';
import type { Progressbar } from '../core/utils/progressbar.js';
Expand Down Expand Up @@ -63,7 +63,7 @@ export interface ViewModelEvents extends ModelEvents {
}
export interface ViewModelOptions<T = ViewModel> extends ModelOptions<T> {
container: HTMLElement;
styles: Style[];
styles: InjectStyle[];

compact: boolean;
darkmode: InitValue;
Expand Down Expand Up @@ -324,7 +324,7 @@ export class ViewModel<
// UI
//

initDom(styles?: Style[]) {
initDom(styles?: InjectStyle[]) {
const wrapper = createElement('div', 'discovery');
const shadow = wrapper.attachShadow({ mode: 'open' });
const readyStyles = injectStyles(shadow, styles);
Expand Down
4 changes: 2 additions & 2 deletions src/preloader.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { InitValue } from './core/darkmode.js';
import type { Style } from './core/utils/inject-styles.js';
import type { InjectStyle } from './core/utils/inject-styles.js';
import type { LoadDataBaseOptions, LoadDataFetchOptions, LoadDataResult } from './core/utils/load-data.js';
import { hasOwn } from './core/utils/object-utils.js';
import { randomId } from './core/utils/id.js';
Expand All @@ -12,7 +12,7 @@ type PushDataLoading = ReturnType<typeof dataSource['push']>;
export type PreloaderOptions = {
dataSource: keyof typeof dataSource;
container: HTMLElement;
styles: Style[];
styles: InjectStyle[];
darkmode: InitValue;
darkmodePersistent: boolean;
embed: boolean;
Expand Down

0 comments on commit 241142b

Please sign in to comment.