@lexriver/dome 2.0.2 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/index.cjs +994 -0
- package/out/index.mjs +2164 -0
- package/out/src/AnimatedArray.d.ts +29 -0
- package/out/src/AnimatedTable.d.mts +2 -1
- package/out/src/AnimatedTable.d.ts +39 -0
- package/out/src/AnimatedTable.mjs +2 -1
- package/out/src/AnimatedText.d.mts +1 -1
- package/out/src/AnimatedText.d.ts +13 -0
- package/out/src/AnimatedText.mjs +1 -1
- package/out/src/Animation.d.ts +4 -0
- package/out/src/Dome.d.ts +9 -0
- package/out/src/Dome.mjs +1 -1
- package/out/src/DomeComponent.d.ts +25 -0
- package/out/src/DomeManipulator.d.ts +52 -0
- package/out/src/DomeRouter.d.ts +32 -0
- package/out/src/LongestCommonSubsequence.d.ts +15 -0
- package/out/src/index.d.mts +5 -1
- package/out/src/index.d.ts +15 -0
- package/out/src/index.mjs +5 -1
- package/package.json +21 -3
- package/out/src/DomeRouter.console-test.d.mts +0 -1
- package/out/src/DomeRouter.console-test.mjs +0 -44
- package/out/src/concurrent-updates.test.d.mts +0 -1
- package/out/src/concurrent-updates.test.mjs +0 -203
- package/out/src/temp-test.d.mts +0 -1
- package/out/src/temp-test.mjs +0 -20
- package/out/vitest.config.d.ts +0 -2
- package/out/vitest.config.js +0 -9
- package/src/AnimatedArray.mts +0 -74
- package/src/AnimatedTable.mts +0 -120
- package/src/AnimatedText.mts +0 -30
- package/src/Animation.mts +0 -4
- package/src/Dome.mts +0 -346
- package/src/DomeComponent.mts +0 -84
- package/src/DomeManipulator.mts +0 -391
- package/src/DomeRouter.console-test.mts +0 -52
- package/src/DomeRouter.mts +0 -287
- package/src/LongestCommonSubsequence.mts +0 -201
- package/src/concurrent-updates.test.mts +0 -252
- package/src/index.mts +0 -12
- package/src/temp-test.mts +0 -23
- package/tsconfig.json +0 -59
- package/vitest.config.ts +0 -10
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Animation } from './Animation';
|
|
2
|
+
interface KeyToElementPair {
|
|
3
|
+
key: string;
|
|
4
|
+
element: HTMLElement;
|
|
5
|
+
}
|
|
6
|
+
export declare class AnimatedArray<T> {
|
|
7
|
+
protected params: {
|
|
8
|
+
parentElement?: HTMLElement;
|
|
9
|
+
array?: T[];
|
|
10
|
+
getKey: (o: T) => string;
|
|
11
|
+
getHtmlElement: (o: T) => HTMLElement;
|
|
12
|
+
animationShow?: Animation;
|
|
13
|
+
animationHide?: Animation;
|
|
14
|
+
emptyList?: HTMLElement;
|
|
15
|
+
};
|
|
16
|
+
arrayOfKeyToElement: KeyToElementPair[];
|
|
17
|
+
constructor(params: {
|
|
18
|
+
parentElement?: HTMLElement;
|
|
19
|
+
array?: T[];
|
|
20
|
+
getKey: (o: T) => string;
|
|
21
|
+
getHtmlElement: (o: T) => HTMLElement;
|
|
22
|
+
animationShow?: Animation;
|
|
23
|
+
animationHide?: Animation;
|
|
24
|
+
emptyList?: HTMLElement;
|
|
25
|
+
});
|
|
26
|
+
get size(): number;
|
|
27
|
+
update(array: T[], parentElement?: HTMLElement | Element): void;
|
|
28
|
+
}
|
|
29
|
+
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ObservableVariable } from '@lexriver/observable';
|
|
2
2
|
import { Animation } from './Animation.mjs';
|
|
3
|
-
import { AnimatedArray
|
|
3
|
+
import { AnimatedArray } from "./AnimatedArray.mjs";
|
|
4
|
+
import { DomeComponent } from "./DomeComponent.mjs";
|
|
4
5
|
interface Attrs<T> {
|
|
5
6
|
isLoadingO?: ObservableVariable<boolean>;
|
|
6
7
|
itemsO: ObservableVariable<T[]>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ObservableVariable } from '@lexriver/observable';
|
|
2
|
+
import { Animation } from './Animation';
|
|
3
|
+
import { AnimatedArray } from "./AnimatedArray";
|
|
4
|
+
import { DomeComponent } from "./DomeComponent";
|
|
5
|
+
interface Attrs<T> {
|
|
6
|
+
isLoadingO?: ObservableVariable<boolean>;
|
|
7
|
+
itemsO: ObservableVariable<T[]>;
|
|
8
|
+
animationShowRow: Animation;
|
|
9
|
+
animationHideRow: Animation;
|
|
10
|
+
animationHideTable?: Animation;
|
|
11
|
+
animationShowTable?: Animation;
|
|
12
|
+
animationHideEmptyList?: Animation;
|
|
13
|
+
animationShowEmptyList?: Animation;
|
|
14
|
+
animationShowLoading?: Animation;
|
|
15
|
+
animationHideLoading?: Animation;
|
|
16
|
+
getKey: (item: T) => string;
|
|
17
|
+
rootElement?: HTMLElement;
|
|
18
|
+
tableElement?: HTMLElement;
|
|
19
|
+
tableBody?: HTMLElement;
|
|
20
|
+
renderTableHead?: (items: T[]) => HTMLElement;
|
|
21
|
+
renderTableRow: (item: T) => HTMLElement;
|
|
22
|
+
renderTableFooter?: (items: T[]) => HTMLElement;
|
|
23
|
+
renderEmptyList: () => HTMLElement;
|
|
24
|
+
renderLoading?: () => HTMLElement;
|
|
25
|
+
}
|
|
26
|
+
export declare class AnimatedTable<T> extends DomeComponent<Attrs<T>> {
|
|
27
|
+
refRoot: HTMLElement;
|
|
28
|
+
refTable: HTMLElement;
|
|
29
|
+
refTableHead: Element;
|
|
30
|
+
refTableBody: HTMLElement;
|
|
31
|
+
refTableFooter: Element;
|
|
32
|
+
refEmptyList: Element;
|
|
33
|
+
refLoading: Element;
|
|
34
|
+
animatedArray: AnimatedArray<T>;
|
|
35
|
+
render(): HTMLElement;
|
|
36
|
+
afterRender(): void;
|
|
37
|
+
updateAsync(): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DomeManipulator } from "./DomeManipulator.mjs";
|
|
2
|
-
import { AnimatedArray
|
|
2
|
+
import { AnimatedArray } from "./AnimatedArray.mjs";
|
|
3
|
+
import { DomeComponent } from "./DomeComponent.mjs";
|
|
3
4
|
export class AnimatedTable extends DomeComponent {
|
|
4
5
|
// rootElement
|
|
5
6
|
// table
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ObservableVariable } from "@lexriver/observable";
|
|
2
2
|
import { CssClass } from "./DomeManipulator.mjs";
|
|
3
|
-
import { DomeComponent } from "./
|
|
3
|
+
import { DomeComponent } from "./DomeComponent.mjs";
|
|
4
4
|
interface Attrs {
|
|
5
5
|
textO: ObservableVariable<string>;
|
|
6
6
|
tag?: string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ObservableVariable } from "@lexriver/observable";
|
|
2
|
+
import { CssClass } from "./DomeManipulator";
|
|
3
|
+
import { DomeComponent } from "./DomeComponent";
|
|
4
|
+
interface Attrs {
|
|
5
|
+
textO: ObservableVariable<string>;
|
|
6
|
+
tag?: string;
|
|
7
|
+
class?: CssClass;
|
|
8
|
+
}
|
|
9
|
+
export declare class AnimatedText extends DomeComponent<Attrs> {
|
|
10
|
+
render(): HTMLElement;
|
|
11
|
+
updateAsync(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export {};
|
package/out/src/AnimatedText.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DomeManipulator } from "./DomeManipulator.mjs";
|
|
2
|
-
import { DomeComponent } from "./
|
|
2
|
+
import { DomeComponent } from "./DomeComponent.mjs";
|
|
3
3
|
export class AnimatedText extends DomeComponent {
|
|
4
4
|
render() {
|
|
5
5
|
//const result = this.attrs.tag ? document.createElement(this.attrs.tag) : document.createElement('span')
|
package/out/src/Dome.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// inspiration: https://github.com/vadimdemedes/dom-chef/blob/master/index.js
|
|
2
|
-
|
|
2
|
+
import { svgTagNames } from 'svg-tag-names';
|
|
3
3
|
import { DataTypes } from '@lexriver/data-types';
|
|
4
4
|
import { checkIfObservable } from '@lexriver/observable';
|
|
5
5
|
import { DomeManipulator } from './DomeManipulator.mjs';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Animation } from './Animation';
|
|
2
|
+
interface InternalAttrs {
|
|
3
|
+
ref?: (ref: any) => void;
|
|
4
|
+
onShowAnimation?: Animation;
|
|
5
|
+
onHideAnimation?: Animation;
|
|
6
|
+
}
|
|
7
|
+
export declare abstract class DomeComponent<Attrs> {
|
|
8
|
+
attrs: Attrs & InternalAttrs;
|
|
9
|
+
children: any;
|
|
10
|
+
rootElement: Element | HTMLElement;
|
|
11
|
+
private updateInProgress;
|
|
12
|
+
private updateRequested;
|
|
13
|
+
constructor(attrs: Attrs & InternalAttrs, children: any);
|
|
14
|
+
protected init(): void;
|
|
15
|
+
protected abstract render(): HTMLElement;
|
|
16
|
+
protected afterRender(): void;
|
|
17
|
+
updateAsync(): Promise<void>;
|
|
18
|
+
private runScheduledUpdateAsync;
|
|
19
|
+
scheduleUpdate: {
|
|
20
|
+
(this: unknown, ...args: [] & any[]): Promise<Promise<void>>;
|
|
21
|
+
cancel: (reason?: any) => void;
|
|
22
|
+
};
|
|
23
|
+
protected afterUpdate(): void;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ObservableVariable } from "@lexriver/observable";
|
|
2
|
+
import { Animation } from './Animation';
|
|
3
|
+
export type CssClass = {
|
|
4
|
+
[key: string]: boolean | ObservableVariable<boolean>;
|
|
5
|
+
} | string[] | string;
|
|
6
|
+
export declare namespace DomeManipulator {
|
|
7
|
+
function hideElementAsync(element: Element, animation?: Animation): Promise<void>;
|
|
8
|
+
function unhideElementAsync(element: Element, animation?: Animation): Promise<void>;
|
|
9
|
+
function insertAsFirstChildAsync(elementToInsert: Element, parentElement: Element | DocumentFragment, animation?: Animation): Promise<void>;
|
|
10
|
+
function insertBeforeAsync(elementToInsert: Element, refElement: Element | null, parentElement: Element | DocumentFragment, animation?: Animation): Promise<void>;
|
|
11
|
+
function insertAfterAsync(elementToInsert: Element, refElement: Element | null | undefined, parentElement: Element | DocumentFragment, animation?: Animation): Promise<void>;
|
|
12
|
+
function insertByIndexAsync(elementToInsert: Element, index: number, parentElement: Element | DocumentFragment, animation?: Animation): Promise<void>;
|
|
13
|
+
function replaceAsync(oldElement: Element, newElement: Element, animationHide?: Animation, animationShow?: Animation): Promise<Element>;
|
|
14
|
+
function removeElementAsync(element: Element, animation?: Animation): Promise<void>;
|
|
15
|
+
function forEachChildrenOf(element: Element, action: (child: ChildNode) => void): void;
|
|
16
|
+
function removeAllChildrenAsync(element: Element, animation?: Animation): Promise<void>;
|
|
17
|
+
function appendChildAsync(containerElement: Element, child: Element, animation?: Animation): Promise<void>;
|
|
18
|
+
function appendChildrenAsync(containerElement: Element, children: Element | Element[] | DocumentFragment | Text | string | null | undefined, animation?: Animation): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Replacements for the same container run in call order. A rejected replacement does
|
|
21
|
+
* not block the queue, and replacements for different containers remain independent.
|
|
22
|
+
*/
|
|
23
|
+
function replaceAllChildrenAsync(containerElement: Element, childrenToInsert: Element | Element[] | DocumentFragment | Text | string | null | undefined, animationForHide?: Animation, animationForShow?: Animation): Promise<void>;
|
|
24
|
+
function isInDom(el: Element | undefined): boolean;
|
|
25
|
+
function isOnScreen(el: Element | undefined): boolean;
|
|
26
|
+
function addCssClassAsync(element: Element, cssClassName: string, removeAfterMs?: number): Promise<void>;
|
|
27
|
+
function addCssClassesAsync(element: Element, cssClassNames: string[], removeAfterMs?: number): Promise<void>;
|
|
28
|
+
function removeCssClass(element: Element, cssClassName: string): void;
|
|
29
|
+
function removeCssClasses(element: Element, cssClassNames: string[]): void;
|
|
30
|
+
/**
|
|
31
|
+
* set css classes by array ['class1', 'class2'] or
|
|
32
|
+
* by object {class1:true, class2:false} or
|
|
33
|
+
* by Observable<boolean> {class1:true, class2:myVarO} or
|
|
34
|
+
* by string
|
|
35
|
+
* this function will replace class attribute so all classes that are not in params will be removed
|
|
36
|
+
* @param value
|
|
37
|
+
* @param element
|
|
38
|
+
*/
|
|
39
|
+
function setCssClasses(element: Element, value: CssClass): void;
|
|
40
|
+
function setAttribute(element: Element, name: string, value: any): void;
|
|
41
|
+
function hasFocus(el: Element): boolean;
|
|
42
|
+
function scrollIntoView(element: Element, paddingFromTop?: number): void;
|
|
43
|
+
const scrollToTop: () => void;
|
|
44
|
+
function getCurrentScrollPosition(): number;
|
|
45
|
+
function scrollToAsync(p: {
|
|
46
|
+
pxFromTop?: number;
|
|
47
|
+
pxFromLeft?: number;
|
|
48
|
+
smooth?: boolean;
|
|
49
|
+
msStep?: number;
|
|
50
|
+
maxMsToWait?: number;
|
|
51
|
+
}): Promise<void>;
|
|
52
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type RouteAction = (params: {
|
|
2
|
+
[key: string]: string | number;
|
|
3
|
+
}, url: string, scrollToPreviousPositionAsync: () => Promise<void>, query: {
|
|
4
|
+
[key: string]: string;
|
|
5
|
+
}) => void | Promise<void>;
|
|
6
|
+
export declare namespace DomeRouter {
|
|
7
|
+
let maxHistoryUrlsCount: number;
|
|
8
|
+
function navigate(url: string): void;
|
|
9
|
+
function goBack(): void;
|
|
10
|
+
function goForward(): void;
|
|
11
|
+
function changeUrl(url: string): void;
|
|
12
|
+
function getCurrentUrl(): string;
|
|
13
|
+
/**
|
|
14
|
+
* get previous page url navigated by router
|
|
15
|
+
* @param previousPageIndex 0=previousPage, 1=previousPage-1, etc
|
|
16
|
+
*/
|
|
17
|
+
function getPreviousPageUrl(previousPageIndex?: number): string | undefined;
|
|
18
|
+
function resolveUrl(url?: string, addToHistory?: boolean): void;
|
|
19
|
+
function onRoute(route: string, exactMatch: boolean, action: RouteAction): void;
|
|
20
|
+
function onNotFound(action: () => void): void;
|
|
21
|
+
/**
|
|
22
|
+
* Check if url matched route.
|
|
23
|
+
* example: /get-product/445345, /get-product/:productId, true ==> Map([productId:445345])
|
|
24
|
+
* example: /get-product/123, /another-route, true ==> undefined
|
|
25
|
+
* example: /articles, /articles, true ==> Map()
|
|
26
|
+
* example: /articles/some-article, /articles, false ==> Map()
|
|
27
|
+
* @param url
|
|
28
|
+
* @param route
|
|
29
|
+
* @param exactMatch
|
|
30
|
+
*/
|
|
31
|
+
function checkUrlMatchRouteAndGetParameters(url: string, route: string, exactMatch?: boolean): Object | undefined;
|
|
32
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare namespace LongestCommonSubsequence {
|
|
2
|
+
function getLongestCommonSubsequence(set1: string[], set2: string[]): string[];
|
|
3
|
+
function getPatch({ oldArray, newArray, onRemove, onAdd }: {
|
|
4
|
+
oldArray: string[];
|
|
5
|
+
newArray: string[];
|
|
6
|
+
onRemove: (index: number, item: string) => void;
|
|
7
|
+
onAdd: (index: number, item: string) => void;
|
|
8
|
+
}): number;
|
|
9
|
+
function getPatchOrdered({ oldArray, newArray, onRemove, onAdd }: {
|
|
10
|
+
oldArray: string[];
|
|
11
|
+
newArray: string[];
|
|
12
|
+
onRemove: (index: number, item: string) => void;
|
|
13
|
+
onAdd: (index: number, item: string) => void;
|
|
14
|
+
}): number;
|
|
15
|
+
}
|
package/out/src/index.d.mts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
export * from '@lexriver/async';
|
|
2
|
+
export { Async, Lock } from '@lexriver/async';
|
|
2
3
|
export * from '@lexriver/data-types';
|
|
4
|
+
export { DataTypes } from '@lexriver/data-types';
|
|
3
5
|
export * from '@lexriver/observable';
|
|
6
|
+
export { ObservableArray, ObservableLocalStorageArray, ObservableLocalStorageVariable, ObservableMap, ObservableVariable, ObservableVariable as ObservableValue, checkIfObservable, createObservable } from '@lexriver/observable';
|
|
4
7
|
export * from '@lexriver/type-event';
|
|
8
|
+
export { TypeEvent } from '@lexriver/type-event';
|
|
5
9
|
export * from './AnimatedArray.mjs';
|
|
6
10
|
export * from './AnimatedTable.mjs';
|
|
7
11
|
export * from './AnimatedText.mjs';
|
|
8
12
|
export * from './Dome.mjs';
|
|
9
13
|
export * from './DomeComponent.mjs';
|
|
10
14
|
export * from './DomeManipulator.mjs';
|
|
11
|
-
export * from './DomeRouter.
|
|
15
|
+
export * from './DomeRouter.mjs';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export * from '@lexriver/async';
|
|
2
|
+
export { Async, Lock } from '@lexriver/async';
|
|
3
|
+
export * from '@lexriver/data-types';
|
|
4
|
+
export { DataTypes } from '@lexriver/data-types';
|
|
5
|
+
export * from '@lexriver/observable';
|
|
6
|
+
export { ObservableArray, ObservableLocalStorageArray, ObservableLocalStorageVariable, ObservableMap, ObservableVariable, ObservableVariable as ObservableValue, checkIfObservable, createObservable } from '@lexriver/observable';
|
|
7
|
+
export * from '@lexriver/type-event';
|
|
8
|
+
export { TypeEvent } from '@lexriver/type-event';
|
|
9
|
+
export * from './AnimatedArray';
|
|
10
|
+
export * from './AnimatedTable';
|
|
11
|
+
export * from './AnimatedText';
|
|
12
|
+
export * from './Dome';
|
|
13
|
+
export * from './DomeComponent';
|
|
14
|
+
export * from './DomeManipulator';
|
|
15
|
+
export * from './DomeRouter';
|
package/out/src/index.mjs
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
export * from '@lexriver/async';
|
|
2
|
+
export { Async, Lock } from '@lexriver/async';
|
|
2
3
|
export * from '@lexriver/data-types';
|
|
4
|
+
export { DataTypes } from '@lexriver/data-types';
|
|
3
5
|
export * from '@lexriver/observable';
|
|
6
|
+
export { ObservableArray, ObservableLocalStorageArray, ObservableLocalStorageVariable, ObservableMap, ObservableVariable, ObservableVariable as ObservableValue, checkIfObservable, createObservable } from '@lexriver/observable';
|
|
4
7
|
export * from '@lexriver/type-event';
|
|
8
|
+
export { TypeEvent } from '@lexriver/type-event';
|
|
5
9
|
export * from './AnimatedArray.mjs';
|
|
6
10
|
export * from './AnimatedTable.mjs';
|
|
7
11
|
export * from './AnimatedText.mjs';
|
|
8
12
|
export * from './Dome.mjs';
|
|
9
13
|
export * from './DomeComponent.mjs';
|
|
10
14
|
export * from './DomeManipulator.mjs';
|
|
11
|
-
export * from './DomeRouter.
|
|
15
|
+
export * from './DomeRouter.mjs';
|
package/package.json
CHANGED
|
@@ -1,13 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"sideEffects": false,
|
|
3
3
|
"name": "@lexriver/dome",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.4",
|
|
5
5
|
"description": "DOM manipulator",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"
|
|
7
|
+
"types": "./out/src/index.d.ts",
|
|
8
|
+
"main": "./out/index.cjs",
|
|
9
|
+
"module": "./out/index.mjs",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./out/src/index.d.mts",
|
|
13
|
+
"import": "./out/src/index.mjs",
|
|
14
|
+
"require": "./out/index.cjs",
|
|
15
|
+
"default": "./out/src/index.mjs"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"out",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
8
22
|
"scripts": {
|
|
9
23
|
"test": "vitest",
|
|
10
|
-
"build": "rimraf out && tsc"
|
|
24
|
+
"build": "rimraf out && tsc && node scripts/build-compat.mjs",
|
|
25
|
+
"test:api-compat": "npm run build && node scripts/test-api-compat.mjs",
|
|
26
|
+
"test:compat": "npm run build && node scripts/test-api-compat.mjs && npm --prefix compatibility/ts39-webpack4 install && npm --prefix compatibility/ts39-webpack4 run build"
|
|
11
27
|
},
|
|
12
28
|
"keywords": [
|
|
13
29
|
"typescript",
|
|
@@ -24,6 +40,7 @@
|
|
|
24
40
|
"license": "MIT",
|
|
25
41
|
"devDependencies": {
|
|
26
42
|
"@types/node": "^22.7.0",
|
|
43
|
+
"esbuild": "^0.21.5",
|
|
27
44
|
"rimraf": "^6.0.1",
|
|
28
45
|
"typescript": "^5.6.2",
|
|
29
46
|
"vitest": "^2.1.1"
|
|
@@ -32,6 +49,7 @@
|
|
|
32
49
|
"@lexriver/async": "^3.0.1",
|
|
33
50
|
"@lexriver/data-types": "^3.0.5",
|
|
34
51
|
"@lexriver/observable": "^3.0.0",
|
|
52
|
+
"@lexriver/type-event": "^2.0.0",
|
|
35
53
|
"svg-tag-names": "^3.0.1",
|
|
36
54
|
"ts-debounce": "^4.0.0"
|
|
37
55
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
// //import { DomeRouter } from "./DomeRouter"
|
|
2
|
-
// function getRouteSlices(route:string){
|
|
3
|
-
// return route.split('/').filter(x => x.length>0)
|
|
4
|
-
// }
|
|
5
|
-
export {};
|
|
6
|
-
// function checkUrlMatchRouteAndGetParameters(url:string, route:string, exactMatch:boolean = true):Map<string,string>|undefined{
|
|
7
|
-
// // this function is purely for export
|
|
8
|
-
// const urlSlices = getRouteSlices(url)
|
|
9
|
-
// const routeSlices = getRouteSlices(route)
|
|
10
|
-
// if(exactMatch && routeSlices.length !== urlSlices.length) return undefined
|
|
11
|
-
// // all routeSlices must match for !exactMatch
|
|
12
|
-
// const extractedParameters = new Map<string,string>()
|
|
13
|
-
// for(let i=0;i<routeSlices.length;i++){
|
|
14
|
-
// let cRouteSlice = routeSlices[i]
|
|
15
|
-
// let cUrlSlice = urlSlices[i] // could be undefined
|
|
16
|
-
// //console.info('\t\t cRouteSlice=', cRouteSlice, 'cUrlSlice=', cUrlSlice)
|
|
17
|
-
// if(cRouteSlice.startsWith(':')){
|
|
18
|
-
// // we have a param name
|
|
19
|
-
// if(cUrlSlice === undefined){
|
|
20
|
-
// return undefined
|
|
21
|
-
// }
|
|
22
|
-
// // we have some variable, save it
|
|
23
|
-
// extractedParameters.set(cRouteSlice.substring(1), cUrlSlice)
|
|
24
|
-
// } else {
|
|
25
|
-
// // no param name
|
|
26
|
-
// if(cRouteSlice !== cUrlSlice){
|
|
27
|
-
// return undefined
|
|
28
|
-
// }
|
|
29
|
-
// }
|
|
30
|
-
// }
|
|
31
|
-
// return extractedParameters
|
|
32
|
-
// }
|
|
33
|
-
// DomeRouter.onRoute('/', true, ()=>{ console.log('exact /')})
|
|
34
|
-
// DomeRouter.onRoute('/', false, ()=>{ console.log('notexact /')})
|
|
35
|
-
// DomeRouter.onRoute('/test', true, ()=>{ console.log('exact /test')})
|
|
36
|
-
// DomeRouter.onRoute('/test/:id', true, (p)=>{ console.log('exact /test/:id', 'params=', p)})
|
|
37
|
-
// DomeRouter.onRoute('/test/:id', false, (p)=>{ console.log('notexact /test/:id', 'params=', p)})
|
|
38
|
-
// DomeRouter.onRoute('/test', false, ()=>{ console.log('notexact /test')})
|
|
39
|
-
// DomeRouter.onRoute('/test/:id/:id2', true, (p)=>{ console.log('exact /test/:id/:id2', 'params=', p)})
|
|
40
|
-
// let testRoute = '//test/34/st'
|
|
41
|
-
// console.log('** testing route:', testRoute)
|
|
42
|
-
// DomeRouter.execute(testRoute)
|
|
43
|
-
// //expect(!true).toBeTruthy()
|
|
44
|
-
//console.log(checkUrlMatchRouteAndGetParameters('/get-product/123', '/get-product/:id/:id2', false))
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import { DomeComponent } from './DomeComponent.mjs';
|
|
3
|
-
import { DomeManipulator } from './DomeManipulator.mjs';
|
|
4
|
-
class FakeElement {
|
|
5
|
-
nodeType = 1;
|
|
6
|
-
childNodes = [];
|
|
7
|
-
classList = {
|
|
8
|
-
values: new Set(),
|
|
9
|
-
add: (name) => this.classList.values.add(name),
|
|
10
|
-
remove: (name) => this.classList.values.delete(name)
|
|
11
|
-
};
|
|
12
|
-
parentNode = null;
|
|
13
|
-
throwOnAppend = false;
|
|
14
|
-
get firstChild() {
|
|
15
|
-
return this.childNodes[0] ?? null;
|
|
16
|
-
}
|
|
17
|
-
appendChild(child) {
|
|
18
|
-
if (child.throwOnAppend) {
|
|
19
|
-
throw new Error('append failed');
|
|
20
|
-
}
|
|
21
|
-
child.parentNode = this;
|
|
22
|
-
this.childNodes.push(child);
|
|
23
|
-
return child;
|
|
24
|
-
}
|
|
25
|
-
remove() {
|
|
26
|
-
if (!this.parentNode)
|
|
27
|
-
return;
|
|
28
|
-
const index = this.parentNode.childNodes.indexOf(this);
|
|
29
|
-
if (index >= 0) {
|
|
30
|
-
this.parentNode.childNodes.splice(index, 1);
|
|
31
|
-
}
|
|
32
|
-
this.parentNode = null;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
const asElement = (element) => element;
|
|
36
|
-
const animation = (name) => ({ cssClassName: name, timeMs: 5 });
|
|
37
|
-
const waitAsync = (timeMs) => new Promise(resolve => setTimeout(resolve, timeMs));
|
|
38
|
-
async function waitForAsync(condition) {
|
|
39
|
-
const timeoutAt = Date.now() + 500;
|
|
40
|
-
while (!condition()) {
|
|
41
|
-
if (Date.now() >= timeoutAt) {
|
|
42
|
-
throw new Error('Timed out waiting for condition');
|
|
43
|
-
}
|
|
44
|
-
await waitAsync(1);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
function deferred() {
|
|
48
|
-
let resolve;
|
|
49
|
-
const promise = new Promise(resolvePromise => {
|
|
50
|
-
resolve = resolvePromise;
|
|
51
|
-
});
|
|
52
|
-
return { promise, resolve };
|
|
53
|
-
}
|
|
54
|
-
const originalNode = Object.getOwnPropertyDescriptor(globalThis, 'Node');
|
|
55
|
-
beforeAll(() => {
|
|
56
|
-
Object.defineProperty(globalThis, 'Node', {
|
|
57
|
-
configurable: true,
|
|
58
|
-
value: { ELEMENT_NODE: 1 }
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
afterAll(() => {
|
|
62
|
-
if (originalNode) {
|
|
63
|
-
Object.defineProperty(globalThis, 'Node', originalNode);
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
delete globalThis.Node;
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
describe('DomeManipulator.replaceAllChildrenAsync', () => {
|
|
70
|
-
async function expectLastQueuedReplacement(animationForHide, animationForShow) {
|
|
71
|
-
const container = new FakeElement();
|
|
72
|
-
const existing = new FakeElement();
|
|
73
|
-
const first = new FakeElement();
|
|
74
|
-
const second = new FakeElement();
|
|
75
|
-
container.appendChild(existing);
|
|
76
|
-
await Promise.all([
|
|
77
|
-
DomeManipulator.replaceAllChildrenAsync(asElement(container), asElement(first), animationForHide, animationForShow),
|
|
78
|
-
DomeManipulator.replaceAllChildrenAsync(asElement(container), asElement(second), animationForHide, animationForShow)
|
|
79
|
-
]);
|
|
80
|
-
expect(container.childNodes).toEqual([second]);
|
|
81
|
-
}
|
|
82
|
-
it('serializes two concurrent replacements without animations', async () => {
|
|
83
|
-
await expectLastQueuedReplacement();
|
|
84
|
-
});
|
|
85
|
-
it('serializes concurrent replacements with a hide animation', async () => {
|
|
86
|
-
await expectLastQueuedReplacement(animation('hide'));
|
|
87
|
-
});
|
|
88
|
-
it('serializes concurrent replacements with a show animation', async () => {
|
|
89
|
-
await expectLastQueuedReplacement(undefined, animation('show'));
|
|
90
|
-
});
|
|
91
|
-
it('serializes concurrent replacements with hide and show animations', async () => {
|
|
92
|
-
await expectLastQueuedReplacement(animation('hide'), animation('show'));
|
|
93
|
-
});
|
|
94
|
-
it('runs replacements on different containers independently', async () => {
|
|
95
|
-
const slowContainer = new FakeElement();
|
|
96
|
-
const fastContainer = new FakeElement();
|
|
97
|
-
const oldSlowChild = new FakeElement();
|
|
98
|
-
const slowChild = new FakeElement();
|
|
99
|
-
const fastChild = new FakeElement();
|
|
100
|
-
slowContainer.appendChild(oldSlowChild);
|
|
101
|
-
let slowReplacementFinished = false;
|
|
102
|
-
const slowReplacement = DomeManipulator.replaceAllChildrenAsync(asElement(slowContainer), asElement(slowChild), { cssClassName: 'hide', timeMs: 30 }).then(() => {
|
|
103
|
-
slowReplacementFinished = true;
|
|
104
|
-
});
|
|
105
|
-
await waitAsync(1);
|
|
106
|
-
await DomeManipulator.replaceAllChildrenAsync(asElement(fastContainer), asElement(fastChild));
|
|
107
|
-
expect(fastContainer.childNodes).toEqual([fastChild]);
|
|
108
|
-
expect(slowReplacementFinished).toBe(false);
|
|
109
|
-
expect(slowContainer.childNodes).toEqual([oldSlowChild]);
|
|
110
|
-
await slowReplacement;
|
|
111
|
-
});
|
|
112
|
-
it('does not let a failed replacement block a later replacement', async () => {
|
|
113
|
-
const container = new FakeElement();
|
|
114
|
-
const failingChild = new FakeElement();
|
|
115
|
-
const successfulChild = new FakeElement();
|
|
116
|
-
failingChild.throwOnAppend = true;
|
|
117
|
-
const failedReplacement = DomeManipulator.replaceAllChildrenAsync(asElement(container), asElement(failingChild));
|
|
118
|
-
const queuedReplacement = DomeManipulator.replaceAllChildrenAsync(asElement(container), asElement(successfulChild));
|
|
119
|
-
await expect(failedReplacement).rejects.toThrow('append failed');
|
|
120
|
-
await queuedReplacement;
|
|
121
|
-
expect(container.childNodes).toEqual([successfulChild]);
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
class ScheduledTestComponent extends DomeComponent {
|
|
125
|
-
updateCount = 0;
|
|
126
|
-
activeUpdates = 0;
|
|
127
|
-
maximumActiveUpdates = 0;
|
|
128
|
-
updateBehavior = async () => undefined;
|
|
129
|
-
render() {
|
|
130
|
-
return {};
|
|
131
|
-
}
|
|
132
|
-
async updateAsync() {
|
|
133
|
-
this.updateCount++;
|
|
134
|
-
this.activeUpdates++;
|
|
135
|
-
this.maximumActiveUpdates = Math.max(this.maximumActiveUpdates, this.activeUpdates);
|
|
136
|
-
try {
|
|
137
|
-
await this.updateBehavior();
|
|
138
|
-
}
|
|
139
|
-
finally {
|
|
140
|
-
this.activeUpdates--;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
describe('DomeComponent.scheduleUpdate', () => {
|
|
145
|
-
it('debounces repeated requests made before an update starts', async () => {
|
|
146
|
-
const component = new ScheduledTestComponent({}, null);
|
|
147
|
-
await Promise.all([
|
|
148
|
-
component.scheduleUpdate(),
|
|
149
|
-
component.scheduleUpdate(),
|
|
150
|
-
component.scheduleUpdate()
|
|
151
|
-
]);
|
|
152
|
-
expect(component.updateCount).toBe(1);
|
|
153
|
-
});
|
|
154
|
-
it('coalesces requests during an update into exactly one follow-up update', async () => {
|
|
155
|
-
const component = new ScheduledTestComponent({}, null);
|
|
156
|
-
const firstUpdate = deferred();
|
|
157
|
-
component.updateBehavior = () => component.updateCount === 1
|
|
158
|
-
? firstUpdate.promise
|
|
159
|
-
: Promise.resolve();
|
|
160
|
-
const initialSchedule = component.scheduleUpdate();
|
|
161
|
-
await waitForAsync(() => component.updateCount === 1);
|
|
162
|
-
component.scheduleUpdate();
|
|
163
|
-
component.scheduleUpdate();
|
|
164
|
-
component.scheduleUpdate();
|
|
165
|
-
await waitAsync(10);
|
|
166
|
-
firstUpdate.resolve();
|
|
167
|
-
await initialSchedule;
|
|
168
|
-
expect(component.updateCount).toBe(2);
|
|
169
|
-
});
|
|
170
|
-
it('never runs scheduled updates concurrently for one component', async () => {
|
|
171
|
-
const component = new ScheduledTestComponent({}, null);
|
|
172
|
-
const firstUpdate = deferred();
|
|
173
|
-
component.updateBehavior = () => component.updateCount === 1
|
|
174
|
-
? firstUpdate.promise
|
|
175
|
-
: Promise.resolve();
|
|
176
|
-
const initialSchedule = component.scheduleUpdate();
|
|
177
|
-
await waitForAsync(() => component.updateCount === 1);
|
|
178
|
-
component.scheduleUpdate();
|
|
179
|
-
await waitAsync(10);
|
|
180
|
-
expect(component.maximumActiveUpdates).toBe(1);
|
|
181
|
-
firstUpdate.resolve();
|
|
182
|
-
await initialSchedule;
|
|
183
|
-
expect(component.maximumActiveUpdates).toBe(1);
|
|
184
|
-
});
|
|
185
|
-
it('allows subsequent scheduled updates after updateAsync rejects', async () => {
|
|
186
|
-
const component = new ScheduledTestComponent({}, null);
|
|
187
|
-
const consoleError = vi.spyOn(console, 'error').mockImplementation(() => undefined);
|
|
188
|
-
component.updateBehavior = async () => {
|
|
189
|
-
if (component.updateCount === 1) {
|
|
190
|
-
throw new Error('update failed');
|
|
191
|
-
}
|
|
192
|
-
};
|
|
193
|
-
try {
|
|
194
|
-
await component.scheduleUpdate();
|
|
195
|
-
await component.scheduleUpdate();
|
|
196
|
-
}
|
|
197
|
-
finally {
|
|
198
|
-
consoleError.mockRestore();
|
|
199
|
-
}
|
|
200
|
-
expect(component.updateCount).toBe(2);
|
|
201
|
-
expect(component.maximumActiveUpdates).toBe(1);
|
|
202
|
-
});
|
|
203
|
-
});
|
package/out/src/temp-test.d.mts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/out/src/temp-test.mjs
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { LongestCommonSubsequence } from "./LongestCommonSubsequence.mjs";
|
|
2
|
-
let oldArray = "ABCD".split('');
|
|
3
|
-
let newArray = "AXYZBCD345".split('');
|
|
4
|
-
const countOfOperations = LongestCommonSubsequence.getPatchOrdered({
|
|
5
|
-
oldArray: [...oldArray],
|
|
6
|
-
newArray: newArray,
|
|
7
|
-
onRemove: (index, item) => {
|
|
8
|
-
console.log('-', item, index);
|
|
9
|
-
oldArray.splice(index, 1);
|
|
10
|
-
},
|
|
11
|
-
onAdd: (index, item) => {
|
|
12
|
-
console.log('+', item, index);
|
|
13
|
-
oldArray.splice(index, 0, item);
|
|
14
|
-
}
|
|
15
|
-
});
|
|
16
|
-
console.log('expecting equal', oldArray, newArray);
|
|
17
|
-
console.log('countOfOperations=', countOfOperations);
|
|
18
|
-
//expect(oldArray).toEqual(newArray)
|
|
19
|
-
// console.log('result oldArray=', oldArray)
|
|
20
|
-
// console.log('result nweArray=', newArray)
|
package/out/vitest.config.d.ts
DELETED