@symfony/ux-live-component 2.27.0 → 2.28.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.
Files changed (36) hide show
  1. package/dist/live.min.css +1 -1
  2. package/dist/live_controller.d.ts +153 -18
  3. package/dist/live_controller.js +3011 -3112
  4. package/package.json +17 -13
  5. package/dist/Backend/Backend.d.ts +0 -31
  6. package/dist/Backend/BackendRequest.d.ts +0 -9
  7. package/dist/Backend/BackendResponse.d.ts +0 -6
  8. package/dist/Backend/RequestBuilder.d.ts +0 -17
  9. package/dist/Component/ElementDriver.d.ts +0 -31
  10. package/dist/Component/UnsyncedInputsTracker.d.ts +0 -28
  11. package/dist/Component/ValueStore.d.ts +0 -17
  12. package/dist/Component/index.d.ts +0 -74
  13. package/dist/Component/plugins/ChildComponentPlugin.d.ts +0 -11
  14. package/dist/Component/plugins/LazyPlugin.d.ts +0 -7
  15. package/dist/Component/plugins/LoadingPlugin.d.ts +0 -23
  16. package/dist/Component/plugins/PageUnloadingPlugin.d.ts +0 -6
  17. package/dist/Component/plugins/PluginInterface.d.ts +0 -4
  18. package/dist/Component/plugins/PollingPlugin.d.ts +0 -10
  19. package/dist/Component/plugins/QueryStringPlugin.d.ts +0 -13
  20. package/dist/Component/plugins/SetValueOntoModelFieldsPlugin.d.ts +0 -6
  21. package/dist/Component/plugins/ValidatedFieldsPlugin.d.ts +0 -6
  22. package/dist/ComponentRegistry.d.ts +0 -8
  23. package/dist/Directive/directives_parser.d.ts +0 -11
  24. package/dist/Directive/get_model_binding.d.ts +0 -9
  25. package/dist/HookManager.d.ts +0 -7
  26. package/dist/PollingDirector.d.ts +0 -16
  27. package/dist/Rendering/ChangingItemsTracker.d.ts +0 -12
  28. package/dist/Rendering/ElementChanges.d.ts +0 -26
  29. package/dist/Rendering/ExternalMutationTracker.d.ts +0 -26
  30. package/dist/Util/getElementAsTagText.d.ts +0 -1
  31. package/dist/data_manipulation_utils.d.ts +0 -2
  32. package/dist/dom_utils.d.ts +0 -10
  33. package/dist/morphdom.d.ts +0 -2
  34. package/dist/normalize_attributes_for_comparison.d.ts +0 -1
  35. package/dist/string_utils.d.ts +0 -3
  36. package/dist/url_utils.d.ts +0 -11
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@symfony/ux-live-component",
3
3
  "description": "Live Component: bring server-side re-rendering & model binding to any element.",
4
4
  "license": "MIT",
5
- "version": "2.27.0",
5
+ "version": "2.28.2",
6
6
  "keywords": [
7
7
  "symfony-ux",
8
8
  "twig",
@@ -17,14 +17,7 @@
17
17
  "main": "dist/live_controller.js",
18
18
  "types": "dist/live_controller.d.ts",
19
19
  "config": {
20
- "css_source": "styles/live.css"
21
- },
22
- "scripts": {
23
- "build": "node ../../../bin/build_package.js .",
24
- "watch": "node ../../../bin/build_package.js . --watch",
25
- "test": "../../../bin/test_package.sh .",
26
- "check": "biome check",
27
- "ci": "biome ci"
20
+ "css_source": "src/live.css"
28
21
  },
29
22
  "symfony": {
30
23
  "controllers": {
@@ -44,17 +37,28 @@
44
37
  "@symfony/ux-live-component": "path:%PACKAGE%/dist/live_controller.js"
45
38
  }
46
39
  },
47
- "dependencies": {
48
- "idiomorph": "^0.3.0"
49
- },
50
40
  "peerDependencies": {
51
41
  "@hotwired/stimulus": "^3.0.0"
52
42
  },
53
43
  "devDependencies": {
54
44
  "@hotwired/stimulus": "^3.0.0",
55
45
  "@testing-library/dom": "^7.31.0",
46
+ "@testing-library/jest-dom": "^6.6.3",
56
47
  "@testing-library/user-event": "^13.1.9",
57
48
  "@types/node-fetch": "^2.6.2",
58
- "node-fetch": "^2.6.1"
49
+ "idiomorph": "^0.3.0",
50
+ "jsdom": "^26.1.0",
51
+ "node-fetch": "^2.6.1",
52
+ "tslib": "^2.8.1",
53
+ "tsx": "^4.20.3",
54
+ "typescript": "^5.8.3",
55
+ "vitest": "^3.2.4"
56
+ },
57
+ "scripts": {
58
+ "build": "tsx ../../../bin/build_package.ts .",
59
+ "watch": "tsx ../../../bin/build_package.ts . --watch",
60
+ "test": "../../../bin/test_package.sh .",
61
+ "check": "biome check",
62
+ "ci": "biome ci"
59
63
  }
60
64
  }
@@ -1,31 +0,0 @@
1
- import BackendRequest from './BackendRequest';
2
- export interface ChildrenFingerprints {
3
- [key: string]: {
4
- fingerprint: string;
5
- tag: string;
6
- };
7
- }
8
- export interface BackendInterface {
9
- makeRequest(props: any, actions: BackendAction[], updated: {
10
- [key: string]: any;
11
- }, children: ChildrenFingerprints, updatedPropsFromParent: {
12
- [key: string]: any;
13
- }, files: {
14
- [key: string]: FileList;
15
- }): BackendRequest;
16
- }
17
- export interface BackendAction {
18
- name: string;
19
- args: Record<string, string>;
20
- }
21
- export default class implements BackendInterface {
22
- private readonly requestBuilder;
23
- constructor(url: string, method?: 'get' | 'post');
24
- makeRequest(props: any, actions: BackendAction[], updated: {
25
- [key: string]: any;
26
- }, children: ChildrenFingerprints, updatedPropsFromParent: {
27
- [key: string]: any;
28
- }, files: {
29
- [key: string]: FileList;
30
- }): BackendRequest;
31
- }
@@ -1,9 +0,0 @@
1
- export default class {
2
- promise: Promise<Response>;
3
- actions: string[];
4
- updatedModels: string[];
5
- isResolved: boolean;
6
- constructor(promise: Promise<Response>, actions: string[], updateModels: string[]);
7
- containsOneOfActions(targetedActions: string[]): boolean;
8
- areAnyModelsUpdated(targetedModels: string[]): boolean;
9
- }
@@ -1,6 +0,0 @@
1
- export default class {
2
- response: Response;
3
- private body;
4
- constructor(response: Response);
5
- getBody(): Promise<string>;
6
- }
@@ -1,17 +0,0 @@
1
- import type { BackendAction, ChildrenFingerprints } from './Backend';
2
- export default class {
3
- private url;
4
- private method;
5
- constructor(url: string, method?: 'get' | 'post');
6
- buildRequest(props: any, actions: BackendAction[], updated: {
7
- [key: string]: any;
8
- }, children: ChildrenFingerprints, updatedPropsFromParent: {
9
- [key: string]: any;
10
- }, files: {
11
- [key: string]: FileList;
12
- }): {
13
- url: string;
14
- fetchOptions: RequestInit;
15
- };
16
- private willDataFitInUrl;
17
- }
@@ -1,31 +0,0 @@
1
- import type LiveControllerDefault from '../live_controller';
2
- export interface ElementDriver {
3
- getModelName(element: HTMLElement): string | null;
4
- getComponentProps(): any;
5
- getEventsToEmit(): Array<{
6
- event: string;
7
- data: any;
8
- target: string | null;
9
- componentName: string | null;
10
- }>;
11
- getBrowserEventsToDispatch(): Array<{
12
- event: string;
13
- payload: any;
14
- }>;
15
- }
16
- export declare class StimulusElementDriver implements ElementDriver {
17
- private readonly controller;
18
- constructor(controller: LiveControllerDefault);
19
- getModelName(element: HTMLElement): string | null;
20
- getComponentProps(): any;
21
- getEventsToEmit(): Array<{
22
- event: string;
23
- data: any;
24
- target: string | null;
25
- componentName: string | null;
26
- }>;
27
- getBrowserEventsToDispatch(): Array<{
28
- event: string;
29
- payload: any;
30
- }>;
31
- }
@@ -1,28 +0,0 @@
1
- import type { ElementDriver } from './ElementDriver';
2
- import type Component from './index';
3
- export default class {
4
- private readonly component;
5
- private readonly modelElementResolver;
6
- private readonly unsyncedInputs;
7
- private elementEventListeners;
8
- constructor(component: Component, modelElementResolver: ElementDriver);
9
- activate(): void;
10
- deactivate(): void;
11
- markModelAsSynced(modelName: string): void;
12
- private handleInputEvent;
13
- private updateModelFromElement;
14
- getUnsyncedInputs(): HTMLElement[];
15
- getUnsyncedModels(): string[];
16
- resetUnsyncedFields(): void;
17
- }
18
- export declare class UnsyncedInputContainer {
19
- private unsyncedModelFields;
20
- private unsyncedNonModelFields;
21
- private unsyncedModelNames;
22
- constructor();
23
- add(element: HTMLElement, modelName?: string | null): void;
24
- resetUnsyncedFields(): void;
25
- allUnsyncedInputs(): HTMLElement[];
26
- markModelAsSynced(modelName: string): void;
27
- getUnsyncedModelNames(): string[];
28
- }
@@ -1,17 +0,0 @@
1
- export default class {
2
- private props;
3
- private dirtyProps;
4
- private pendingProps;
5
- private updatedPropsFromParent;
6
- constructor(props: any);
7
- get(name: string): any;
8
- has(name: string): boolean;
9
- set(name: string, value: any): boolean;
10
- getOriginalProps(): any;
11
- getDirtyProps(): any;
12
- getUpdatedPropsFromParent(): any;
13
- flushDirtyPropsToPending(): void;
14
- reinitializeAllProps(props: any): void;
15
- pushPendingPropsBackToDirty(): void;
16
- storeNewPropsFromParent(props: any): boolean;
17
- }
@@ -1,74 +0,0 @@
1
- import type { BackendInterface } from '../Backend/Backend';
2
- import type BackendRequest from '../Backend/BackendRequest';
3
- import BackendResponse from '../Backend/BackendResponse';
4
- import type { ElementDriver } from './ElementDriver';
5
- import type { PluginInterface } from './plugins/PluginInterface';
6
- import ValueStore from './ValueStore';
7
- type MaybePromise<T = void> = T | Promise<T>;
8
- export type ComponentHooks = {
9
- connect: (component: Component) => MaybePromise;
10
- disconnect: (component: Component) => MaybePromise;
11
- 'request:started': (requestConfig: any) => MaybePromise;
12
- 'render:finished': (component: Component) => MaybePromise;
13
- 'response:error': (backendResponse: BackendResponse, controls: {
14
- displayError: boolean;
15
- }) => MaybePromise;
16
- 'loading.state:started': (element: HTMLElement, request: BackendRequest) => MaybePromise;
17
- 'loading.state:finished': (element: HTMLElement) => MaybePromise;
18
- 'model:set': (model: string, value: any, component: Component) => MaybePromise;
19
- };
20
- export type ComponentHookName = keyof ComponentHooks;
21
- export type ComponentHookCallback<T extends string = ComponentHookName> = T extends ComponentHookName ? ComponentHooks[T] : (...args: any[]) => MaybePromise;
22
- export default class Component {
23
- readonly element: HTMLElement;
24
- readonly name: string;
25
- readonly listeners: Map<string, string[]>;
26
- private backend;
27
- readonly elementDriver: ElementDriver;
28
- id: string | null;
29
- fingerprint: string;
30
- readonly valueStore: ValueStore;
31
- private readonly unsyncedInputsTracker;
32
- private hooks;
33
- defaultDebounce: number;
34
- private backendRequest;
35
- private pendingActions;
36
- private pendingFiles;
37
- private isRequestPending;
38
- private requestDebounceTimeout;
39
- private nextRequestPromise;
40
- private nextRequestPromiseResolve;
41
- private externalMutationTracker;
42
- constructor(element: HTMLElement, name: string, props: any, listeners: Array<{
43
- event: string;
44
- action: string;
45
- }>, id: string | null, backend: BackendInterface, elementDriver: ElementDriver);
46
- addPlugin(plugin: PluginInterface): void;
47
- connect(): void;
48
- disconnect(): void;
49
- on<T extends string | ComponentHookName = ComponentHookName>(hookName: T, callback: ComponentHookCallback<T>): void;
50
- off<T extends string | ComponentHookName = ComponentHookName>(hookName: T, callback: ComponentHookCallback<T>): void;
51
- set(model: string, value: any, reRender?: boolean, debounce?: number | boolean): Promise<BackendResponse>;
52
- getData(model: string): any;
53
- action(name: string, args?: any, debounce?: number | boolean): Promise<BackendResponse>;
54
- files(key: string, input: HTMLInputElement): void;
55
- render(): Promise<BackendResponse>;
56
- getUnsyncedModels(): string[];
57
- emit(name: string, data: any, onlyMatchingComponentsNamed?: string | null): void;
58
- emitUp(name: string, data: any, onlyMatchingComponentsNamed?: string | null): void;
59
- emitSelf(name: string, data: any): void;
60
- private performEmit;
61
- private doEmit;
62
- private isTurboEnabled;
63
- private tryStartingRequest;
64
- private performRequest;
65
- private processRerender;
66
- private calculateDebounce;
67
- private clearRequestDebounceTimeout;
68
- private debouncedStartRequest;
69
- private renderError;
70
- private resetPromise;
71
- _updateFromParentProps(props: any): void;
72
- }
73
- export declare function proxifyComponent(component: Component): Component;
74
- export {};
@@ -1,11 +0,0 @@
1
- import type Component from '../../Component';
2
- import type { PluginInterface } from './PluginInterface';
3
- export default class implements PluginInterface {
4
- private readonly component;
5
- private parentModelBindings;
6
- constructor(component: Component);
7
- attachToComponent(component: Component): void;
8
- private getChildrenFingerprints;
9
- private notifyParentModelChange;
10
- private getChildren;
11
- }
@@ -1,7 +0,0 @@
1
- import type Component from '../index';
2
- import type { PluginInterface } from './PluginInterface';
3
- export default class implements PluginInterface {
4
- private intersectionObserver;
5
- attachToComponent(component: Component): void;
6
- private getObserver;
7
- }
@@ -1,23 +0,0 @@
1
- import type BackendRequest from '../../Backend/BackendRequest';
2
- import type Component from '../../Component';
3
- import { type Directive } from '../../Directive/directives_parser';
4
- import type { PluginInterface } from './PluginInterface';
5
- interface ElementLoadingDirectives {
6
- element: HTMLElement | SVGElement;
7
- directives: Directive[];
8
- }
9
- export default class implements PluginInterface {
10
- attachToComponent(component: Component): void;
11
- startLoading(component: Component, targetElement: HTMLElement | SVGElement, backendRequest: BackendRequest): void;
12
- finishLoading(component: Component, targetElement: HTMLElement | SVGElement): void;
13
- private handleLoadingToggle;
14
- private handleLoadingDirective;
15
- getLoadingDirectives(component: Component, element: HTMLElement | SVGElement): ElementLoadingDirectives[];
16
- private showElement;
17
- private hideElement;
18
- private addClass;
19
- private removeClass;
20
- private addAttributes;
21
- private removeAttributes;
22
- }
23
- export {};
@@ -1,6 +0,0 @@
1
- import type Component from '../index';
2
- import type { PluginInterface } from './PluginInterface';
3
- export default class implements PluginInterface {
4
- private isConnected;
5
- attachToComponent(component: Component): void;
6
- }
@@ -1,4 +0,0 @@
1
- import type Component from '../index';
2
- export interface PluginInterface {
3
- attachToComponent(component: Component): void;
4
- }
@@ -1,10 +0,0 @@
1
- import type Component from '../index';
2
- import type { PluginInterface } from './PluginInterface';
3
- export default class implements PluginInterface {
4
- private element;
5
- private pollingDirector;
6
- attachToComponent(component: Component): void;
7
- addPoll(actionName: string, duration: number): void;
8
- clearPolling(): void;
9
- private initializePolling;
10
- }
@@ -1,13 +0,0 @@
1
- import type Component from '../index';
2
- import type { PluginInterface } from './PluginInterface';
3
- interface QueryMapping {
4
- name: string;
5
- }
6
- export default class implements PluginInterface {
7
- private readonly mapping;
8
- constructor(mapping: {
9
- [p: string]: QueryMapping;
10
- });
11
- attachToComponent(component: Component): void;
12
- }
13
- export {};
@@ -1,6 +0,0 @@
1
- import type Component from '../index';
2
- import type { PluginInterface } from './PluginInterface';
3
- export default class implements PluginInterface {
4
- attachToComponent(component: Component): void;
5
- private synchronizeValueOfModelFields;
6
- }
@@ -1,6 +0,0 @@
1
- import type Component from '../index';
2
- import type { PluginInterface } from './PluginInterface';
3
- export default class implements PluginInterface {
4
- attachToComponent(component: Component): void;
5
- private handleModelSet;
6
- }
@@ -1,8 +0,0 @@
1
- import type Component from './Component';
2
- export declare const resetRegistry: () => void;
3
- export declare const registerComponent: (component: Component) => void;
4
- export declare const unregisterComponent: (component: Component) => void;
5
- export declare const getComponent: (element: HTMLElement) => Promise<Component>;
6
- export declare const findComponents: (currentComponent: Component, onlyParents: boolean, onlyMatchName: string | null) => Component[];
7
- export declare const findChildren: (currentComponent: Component) => Component[];
8
- export declare const findParent: (currentComponent: Component) => Component | null;
@@ -1,11 +0,0 @@
1
- export interface DirectiveModifier {
2
- name: string;
3
- value: string | null;
4
- }
5
- export interface Directive {
6
- action: string;
7
- args: string[];
8
- modifiers: DirectiveModifier[];
9
- getString: () => string;
10
- }
11
- export declare function parseDirectives(content: string | null): Directive[];
@@ -1,9 +0,0 @@
1
- import type { Directive } from './directives_parser';
2
- export interface ModelBinding {
3
- modelName: string;
4
- innerModelName: string | null;
5
- shouldRender: boolean;
6
- debounce: number | boolean;
7
- targetEventName: string | null;
8
- }
9
- export default function (modelDirective: Directive): ModelBinding;
@@ -1,7 +0,0 @@
1
- import type { ComponentHookCallback, ComponentHookName } from './Component';
2
- export default class {
3
- private hooks;
4
- register<T extends string | ComponentHookName = ComponentHookName>(hookName: T, callback: ComponentHookCallback<T>): void;
5
- unregister<T extends string | ComponentHookName = ComponentHookName>(hookName: T, callback: ComponentHookCallback<T>): void;
6
- triggerHook<T extends string | ComponentHookName = ComponentHookName>(hookName: T, ...args: Parameters<ComponentHookCallback<T>>): void;
7
- }
@@ -1,16 +0,0 @@
1
- import type Component from './Component';
2
- export default class {
3
- component: Component;
4
- isPollingActive: boolean;
5
- polls: Array<{
6
- actionName: string;
7
- duration: number;
8
- }>;
9
- pollingIntervals: number[];
10
- constructor(component: Component);
11
- addPoll(actionName: string, duration: number): void;
12
- startAllPolling(): void;
13
- stopAllPolling(): void;
14
- clearPolling(): void;
15
- private initiatePoll;
16
- }
@@ -1,12 +0,0 @@
1
- export default class {
2
- private changedItems;
3
- private removedItems;
4
- setItem(itemName: string, newValue: string, previousValue: string | null): void;
5
- removeItem(itemName: string, currentValue: string | null): void;
6
- getChangedItems(): {
7
- name: string;
8
- value: string;
9
- }[];
10
- getRemovedItems(): string[];
11
- isEmpty(): boolean;
12
- }
@@ -1,26 +0,0 @@
1
- export default class ElementChanges {
2
- private addedClasses;
3
- private removedClasses;
4
- private styleChanges;
5
- private attributeChanges;
6
- addClass(className: string): void;
7
- removeClass(className: string): void;
8
- addStyle(styleName: string, newValue: string, originalValue: string | null): void;
9
- removeStyle(styleName: string, originalValue: string): void;
10
- addAttribute(attributeName: string, newValue: string, originalValue: string | null): void;
11
- removeAttribute(attributeName: string, originalValue: string | null): void;
12
- getAddedClasses(): string[];
13
- getRemovedClasses(): string[];
14
- getChangedStyles(): {
15
- name: string;
16
- value: string;
17
- }[];
18
- getRemovedStyles(): string[];
19
- getChangedAttributes(): {
20
- name: string;
21
- value: string;
22
- }[];
23
- getRemovedAttributes(): string[];
24
- applyToElement(element: HTMLElement): void;
25
- isEmpty(): boolean;
26
- }
@@ -1,26 +0,0 @@
1
- import ElementChanges from './ElementChanges';
2
- export default class {
3
- private element;
4
- private shouldTrackChangeCallback;
5
- private mutationObserver;
6
- private changedElements;
7
- changedElementsCount: number;
8
- private addedElements;
9
- private removedElements;
10
- private isStarted;
11
- constructor(element: Element, shouldTrackChangeCallback: (element: Element) => boolean);
12
- start(): void;
13
- stop(): void;
14
- getChangedElement(element: Element): ElementChanges | null;
15
- getAddedElements(): Element[];
16
- wasElementAdded(element: Element): boolean;
17
- handlePendingChanges(): void;
18
- private onMutations;
19
- private handleChildListMutation;
20
- private handleAttributeMutation;
21
- private handleClassAttributeMutation;
22
- private handleStyleAttributeMutation;
23
- private handleGenericAttributeMutation;
24
- private extractStyles;
25
- private isElementAddedByTranslation;
26
- }
@@ -1 +0,0 @@
1
- export default function getElementAsTagText(element: HTMLElement): string;
@@ -1,2 +0,0 @@
1
- export declare function getDeepData(data: any, propertyPath: string): any;
2
- export declare function setDeepData(data: any, propertyPath: string, value: any): any;
@@ -1,10 +0,0 @@
1
- import type Component from './Component';
2
- import type ValueStore from './Component/ValueStore';
3
- import { type Directive } from './Directive/directives_parser';
4
- export declare function getValueFromElement(element: HTMLElement, valueStore: ValueStore): string | string[] | null | boolean;
5
- export declare function setValueOnElement(element: HTMLElement, value: any): void;
6
- export declare function getAllModelDirectiveFromElements(element: HTMLElement): Directive[];
7
- export declare function getModelDirectiveFromElement(element: HTMLElement, throwOnMissing?: boolean): null | Directive;
8
- export declare function elementBelongsToThisComponent(element: Element, component: Component): boolean;
9
- export declare function cloneHTMLElement(element: HTMLElement): HTMLElement;
10
- export declare function htmlToElement(html: string): HTMLElement;
@@ -1,2 +0,0 @@
1
- import type ExternalMutationTracker from './Rendering/ExternalMutationTracker';
2
- export declare function executeMorphdom(rootFromElement: HTMLElement, rootToElement: HTMLElement, modifiedFieldElements: Array<HTMLElement>, getElementValue: (element: HTMLElement) => any, externalMutationTracker: ExternalMutationTracker): void;
@@ -1 +0,0 @@
1
- export declare function normalizeAttributesForComparison(element: HTMLElement): void;
@@ -1,3 +0,0 @@
1
- export declare function combineSpacedArray(parts: Array<string>): string[];
2
- export declare function trimAll(str: string): string;
3
- export declare function normalizeModelName(model: string): string;
@@ -1,11 +0,0 @@
1
- export declare class UrlUtils extends URL {
2
- has(key: string): boolean;
3
- set(key: string, value: any): void;
4
- get(key: string): any | undefined;
5
- remove(key: string): void;
6
- private getData;
7
- private setData;
8
- }
9
- export declare class HistoryStrategy {
10
- static replace(url: URL): void;
11
- }