chayns-api 3.0.0-beta.4 → 3.1.0-beta.0
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/README.md +4 -11
- package/dist/cjs/calls/index.js +4 -1
- package/dist/cjs/calls/visibilityChangeListener.js +4 -4
- package/dist/cjs/components/ChaynsProvider.js +34 -6
- package/dist/cjs/components/withHydrationBoundary.js +2 -2
- package/dist/cjs/constants/index.js +0 -22
- package/dist/cjs/contexts/HistoryLayerContext.js +89 -0
- package/dist/cjs/contexts/index.js +38 -0
- package/dist/cjs/handler/history/FrameHistoryLayer.js +100 -0
- package/dist/cjs/handler/history/HistoryLayer.js +321 -0
- package/dist/cjs/handler/history/index.js +19 -0
- package/dist/cjs/hooks/history.js +454 -0
- package/dist/cjs/hooks/index.js +62 -1
- package/dist/cjs/host/ChaynsHost.js +113 -54
- package/dist/cjs/host/iframe/HostIframe.js +70 -5
- package/dist/cjs/host/module/ModuleHost.js +50 -44
- package/dist/cjs/index.js +139 -6
- package/dist/cjs/types/history.js +1 -0
- package/dist/cjs/umd.index.js +2 -2
- package/dist/cjs/utils/EventBus.js +33 -0
- package/dist/cjs/{util → utils}/appStorage.js +2 -2
- package/dist/cjs/utils/equality.js +19 -0
- package/dist/cjs/utils/history/BlockRegistry.js +110 -0
- package/dist/cjs/utils/history/NavigationQueue.js +388 -0
- package/dist/cjs/utils/history/layerTree.js +32 -0
- package/dist/cjs/utils/history/navigationIndex.js +42 -0
- package/dist/cjs/utils/history/rootLayer.js +175 -0
- package/dist/cjs/utils/history/segments.js +15 -0
- package/dist/cjs/utils/history/stateProjector.js +156 -0
- package/dist/cjs/utils/history/url.js +47 -0
- package/dist/cjs/utils/history/window.js +9 -0
- package/dist/cjs/wrapper/AppWrapper.js +23 -23
- package/dist/cjs/wrapper/FrameWrapper.js +35 -2
- package/dist/cjs/wrapper/ModuleFederationWrapper.js +2 -0
- package/dist/cjs/wrapper/StaticChaynsApi.js +1 -1
- package/dist/esm/calls/index.js +2 -0
- package/dist/esm/calls/visibilityChangeListener.js +1 -1
- package/dist/esm/components/ChaynsProvider.js +34 -6
- package/dist/esm/components/withHydrationBoundary.js +1 -1
- package/dist/esm/constants/index.js +1 -3
- package/dist/esm/contexts/HistoryLayerContext.js +76 -0
- package/dist/esm/contexts/index.js +3 -0
- package/dist/esm/handler/history/FrameHistoryLayer.js +105 -0
- package/dist/esm/handler/history/HistoryLayer.js +321 -0
- package/dist/esm/handler/history/index.js +2 -0
- package/dist/esm/hooks/history.js +428 -0
- package/dist/esm/hooks/index.js +2 -1
- package/dist/esm/host/ChaynsHost.js +113 -54
- package/dist/esm/host/iframe/HostIframe.js +70 -5
- package/dist/esm/host/module/ModuleHost.js +50 -44
- package/dist/esm/index.js +15 -6
- package/dist/esm/types/history.js +1 -0
- package/dist/esm/umd.index.js +2 -2
- package/dist/esm/utils/EventBus.js +31 -0
- package/dist/esm/{util → utils}/appStorage.js +1 -1
- package/dist/esm/utils/equality.js +12 -0
- package/dist/esm/utils/history/BlockRegistry.js +108 -0
- package/dist/esm/utils/history/NavigationQueue.js +385 -0
- package/dist/esm/utils/history/layerTree.js +24 -0
- package/dist/esm/utils/history/navigationIndex.js +33 -0
- package/dist/esm/utils/history/rootLayer.js +167 -0
- package/dist/esm/utils/history/segments.js +7 -0
- package/dist/esm/utils/history/stateProjector.js +147 -0
- package/dist/esm/utils/history/url.js +40 -0
- package/dist/esm/utils/history/window.js +3 -0
- package/dist/esm/wrapper/AppWrapper.js +5 -5
- package/dist/esm/wrapper/FrameWrapper.js +35 -2
- package/dist/esm/wrapper/ModuleFederationWrapper.js +2 -0
- package/dist/esm/wrapper/StaticChaynsApi.js +2 -1
- package/dist/types/calls/index.d.ts +5 -0
- package/dist/types/components/ChaynsProvider.d.ts +21 -0
- package/dist/types/constants/index.d.ts +0 -2
- package/dist/types/contexts/HistoryLayerContext.d.ts +33 -0
- package/dist/types/contexts/index.d.ts +3 -0
- package/dist/types/handler/history/FrameHistoryLayer.d.ts +99 -0
- package/dist/types/handler/history/HistoryLayer.d.ts +117 -0
- package/dist/types/handler/history/index.d.ts +2 -0
- package/dist/types/hooks/history.d.ts +89 -0
- package/dist/types/hooks/index.d.ts +1 -0
- package/dist/types/host/ChaynsHost.d.ts +12 -0
- package/dist/types/host/iframe/HostIframe.d.ts +4 -0
- package/dist/types/host/module/ModuleHost.d.ts +4 -0
- package/dist/types/index.d.ts +15 -6
- package/dist/types/types/IChaynsReact.d.ts +3 -0
- package/dist/types/types/history.d.ts +74 -0
- package/dist/types/umd.index.d.ts +2 -2
- package/dist/types/utils/EventBus.d.ts +10 -0
- package/dist/types/{util → utils}/collectCssChunks.d.ts +1 -1
- package/dist/types/utils/equality.d.ts +2 -0
- package/dist/types/utils/history/BlockRegistry.d.ts +38 -0
- package/dist/types/utils/history/NavigationQueue.d.ts +109 -0
- package/dist/types/utils/history/layerTree.d.ts +10 -0
- package/dist/types/utils/history/navigationIndex.d.ts +14 -0
- package/dist/types/utils/history/rootLayer.d.ts +42 -0
- package/dist/types/utils/history/segments.d.ts +2 -0
- package/dist/types/utils/history/stateProjector.d.ts +24 -0
- package/dist/types/utils/history/url.d.ts +17 -0
- package/dist/types/utils/history/window.d.ts +1 -0
- package/dist/types/wrapper/FrameWrapper.d.ts +1 -0
- package/dist/types/wrapper/StaticChaynsApi.d.ts +1 -0
- package/package.json +2 -1
- /package/dist/cjs/{constants → contexts}/hydrationContext.js +0 -0
- /package/dist/cjs/{constants → contexts}/moduleContext.js +0 -0
- /package/dist/cjs/{helper/apiListenerHelper.js → utils/apiListener.js} +0 -0
- /package/dist/cjs/{util → utils}/appCall.js +0 -0
- /package/dist/cjs/{util → utils}/bindChaynsApi.js +0 -0
- /package/dist/cjs/{util → utils}/collectCssChunks.js +0 -0
- /package/dist/cjs/{util → utils}/deviceHelper.js +0 -0
- /package/dist/cjs/{util → utils}/heightHelper.js +0 -0
- /package/dist/cjs/{util → utils}/initModuleFederationSharing.js +0 -0
- /package/dist/cjs/{util → utils}/is.js +0 -0
- /package/dist/cjs/{util → utils}/postIframeForm.js +0 -0
- /package/dist/cjs/{util → utils}/transferNestedFunctions.js +0 -0
- /package/dist/cjs/{util → utils}/url.js +0 -0
- /package/dist/esm/{constants → contexts}/hydrationContext.js +0 -0
- /package/dist/esm/{constants → contexts}/moduleContext.js +0 -0
- /package/dist/esm/{helper/apiListenerHelper.js → utils/apiListener.js} +0 -0
- /package/dist/esm/{util → utils}/appCall.js +0 -0
- /package/dist/esm/{util → utils}/bindChaynsApi.js +0 -0
- /package/dist/esm/{util → utils}/collectCssChunks.js +0 -0
- /package/dist/esm/{util → utils}/deviceHelper.js +0 -0
- /package/dist/esm/{util → utils}/heightHelper.js +0 -0
- /package/dist/esm/{util → utils}/initModuleFederationSharing.js +0 -0
- /package/dist/esm/{util → utils}/is.js +0 -0
- /package/dist/esm/{util → utils}/postIframeForm.js +0 -0
- /package/dist/esm/{util → utils}/transferNestedFunctions.js +0 -0
- /package/dist/esm/{util → utils}/url.js +0 -0
- /package/dist/types/{constants → contexts}/hydrationContext.d.ts +0 -0
- /package/dist/types/{constants → contexts}/moduleContext.d.ts +0 -0
- /package/dist/types/{helper/apiListenerHelper.d.ts → utils/apiListener.d.ts} +0 -0
- /package/dist/types/{util → utils}/appCall.d.ts +0 -0
- /package/dist/types/{util → utils}/appStorage.d.ts +0 -0
- /package/dist/types/{util → utils}/bindChaynsApi.d.ts +0 -0
- /package/dist/types/{util → utils}/deviceHelper.d.ts +0 -0
- /package/dist/types/{util → utils}/heightHelper.d.ts +0 -0
- /package/dist/types/{util → utils}/initModuleFederationSharing.d.ts +0 -0
- /package/dist/types/{util → utils}/is.d.ts +0 -0
- /package/dist/types/{util → utils}/postIframeForm.d.ts +0 -0
- /package/dist/types/{util → utils}/transferNestedFunctions.d.ts +0 -0
- /package/dist/types/{util → utils}/url.d.ts +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { ChaynsHistoryLayer, ChaynsHistoryNavigateOptions, ChaynsHistoryNavigationCommitOptions, ChaynsHistoryBlockOptions, ChaynsHistoryLayerEvent, ChaynsHistoryActionResult } from '../types/history';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves the active ChaynsHistoryLayer: context first, then
|
|
4
|
+
* `chaynsHost.history.getOwnLayer()` if available, then throws in dev.
|
|
5
|
+
*/
|
|
6
|
+
export declare function useChaynsHistoryLayer(): ChaynsHistoryLayer;
|
|
7
|
+
export interface UseChaynsHistoryRouteResult {
|
|
8
|
+
segments: string[];
|
|
9
|
+
setRoute: (route: string | string[], opts?: ChaynsHistoryNavigateOptions) => void;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Returns the current route segments and a setter for the nearest ChaynsHistoryLayer.
|
|
13
|
+
* Re-renders only when the segments change.
|
|
14
|
+
*/
|
|
15
|
+
export declare function useChaynsHistoryRoute(): UseChaynsHistoryRouteResult;
|
|
16
|
+
/**
|
|
17
|
+
* Returns the current layer state and a setter.
|
|
18
|
+
* Re-renders only when the own-state changes (shallow comparison performed by layer).
|
|
19
|
+
*/
|
|
20
|
+
export declare function useChaynsHistoryState<T extends object = Record<string, unknown>>(): [
|
|
21
|
+
T | undefined,
|
|
22
|
+
(state: T, opts?: ChaynsHistoryNavigateOptions) => void
|
|
23
|
+
];
|
|
24
|
+
/**
|
|
25
|
+
* Returns a stable `navigate` function for the nearest ChaynsHistoryLayer.
|
|
26
|
+
*/
|
|
27
|
+
export declare function useChaynsHistoryNavigate(): (opts: {
|
|
28
|
+
route?: string | string[];
|
|
29
|
+
state?: Record<string, unknown>;
|
|
30
|
+
/** Switch the active child as part of this navigation. Auto-creates the child if needed. */
|
|
31
|
+
activeChild?: string | null;
|
|
32
|
+
/** Initial route/state to seed the child with when it is first activated. */
|
|
33
|
+
activeChildInit?: {
|
|
34
|
+
route?: string | string[];
|
|
35
|
+
state?: Record<string, unknown>;
|
|
36
|
+
};
|
|
37
|
+
} & ChaynsHistoryNavigateOptions) => Promise<ChaynsHistoryActionResult>;
|
|
38
|
+
/**
|
|
39
|
+
* Returns the current query params and a setter for the nearest ChaynsHistoryLayer.
|
|
40
|
+
* Setter replaces all params on this layer; merge manually if needed:
|
|
41
|
+
* `setParams({ ...params, newKey: 'val' })`.
|
|
42
|
+
* Re-renders only when params change.
|
|
43
|
+
*/
|
|
44
|
+
export declare function useChaynsHistoryParams(): [
|
|
45
|
+
Record<string, string>,
|
|
46
|
+
(params: Record<string, string>, opts?: ChaynsHistoryNavigationCommitOptions) => void
|
|
47
|
+
];
|
|
48
|
+
/**
|
|
49
|
+
* Returns the current hash fragment (without `#`) and a setter for the nearest ChaynsHistoryLayer.
|
|
50
|
+
* Pass `''` to explicitly clear the hash.
|
|
51
|
+
* Re-renders only when the hash changes.
|
|
52
|
+
*/
|
|
53
|
+
export declare function useChaynsHistoryHash(): [string, (hash: string, opts?: ChaynsHistoryNavigationCommitOptions) => void];
|
|
54
|
+
export interface UseChaynsHistoryBlockOptions extends ChaynsHistoryBlockOptions {
|
|
55
|
+
/** Only register the block when true. Default: true. */
|
|
56
|
+
isEnabled?: boolean;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Registers a navigation blocker. The callback must return a Promise<boolean>:
|
|
60
|
+
* true = allow, false = block.
|
|
61
|
+
*
|
|
62
|
+
* The caller is responsible for providing a stable `callback` reference
|
|
63
|
+
* (e.g. via useCallback) — registrations only change when the reference changes.
|
|
64
|
+
* `scope` and `isBeforeUnload` are read when the block is registered; changes
|
|
65
|
+
* after mount are applied on the next registration cycle.
|
|
66
|
+
*/
|
|
67
|
+
export declare function useChaynsHistoryBlock(callback: () => Promise<boolean>, opts?: UseChaynsHistoryBlockOptions): void;
|
|
68
|
+
/**
|
|
69
|
+
* Low-level subscription to `change` or `popstate` events on the nearest layer.
|
|
70
|
+
*/
|
|
71
|
+
export declare function useChaynsHistoryEvent(type: 'change' | 'popstate', handler: (e: ChaynsHistoryLayerEvent) => void): void;
|
|
72
|
+
/**
|
|
73
|
+
* Returns the child layer with the given id, creating it on mount if it
|
|
74
|
+
* doesn't already exist. Does NOT destroy the layer on unmount — the caller
|
|
75
|
+
* must explicitly call `layer.destroyChildLayer(id)` to remove it.
|
|
76
|
+
*/
|
|
77
|
+
export declare function useChaynsHistoryChildLayer(id: string): ChaynsHistoryLayer;
|
|
78
|
+
export interface UseChaynsHistoryActiveChildResult {
|
|
79
|
+
activeChildId: string | null;
|
|
80
|
+
setActiveChild: (id: string | null, init?: {
|
|
81
|
+
route?: string[];
|
|
82
|
+
state?: Record<string, unknown>;
|
|
83
|
+
}) => void;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Returns the active child id of the nearest layer and a setter.
|
|
87
|
+
*/
|
|
88
|
+
export declare function useChaynsHistoryActiveChild(): UseChaynsHistoryActiveChildResult;
|
|
89
|
+
export { ChaynsHistoryLayerProvider, useChaynsHistoryLayerContext } from '../contexts/HistoryLayerContext';
|
|
@@ -19,3 +19,4 @@ export { useCustomCallbackFunction } from './useCustomCallbackFunction';
|
|
|
19
19
|
export { useCustomFunction } from './useCustomFunction';
|
|
20
20
|
export { useStyleSettings } from './useStyleSettings';
|
|
21
21
|
export { useChaynsApiId } from './useChaynsApiId';
|
|
22
|
+
export { useChaynsHistoryLayer, useChaynsHistoryRoute, useChaynsHistoryParams, useChaynsHistoryHash, useChaynsHistoryState, useChaynsHistoryNavigate, useChaynsHistoryBlock, useChaynsHistoryEvent, useChaynsHistoryChildLayer, useChaynsHistoryActiveChild, type UseChaynsHistoryRouteResult, type UseChaynsHistoryActiveChildResult, type UseChaynsHistoryBlockOptions, } from './history';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { FC } from 'react';
|
|
2
2
|
import { TypeSystem } from './module/ModuleHost';
|
|
3
3
|
import { ChaynsApiDevice, ChaynsApiSite, ChaynsApiUser, ChaynsReactFunctions, ChaynsReactValues, IChaynsReact, Page } from '../types/IChaynsReact';
|
|
4
|
+
import { ChaynsHistoryLayer } from '../types/history';
|
|
4
5
|
type ChaynsHostType = {
|
|
5
6
|
type: `${'client' | 'server'}-${'iframe' | 'module'}`;
|
|
6
7
|
iFrameProps?: {
|
|
@@ -26,6 +27,17 @@ type ChaynsHostType = {
|
|
|
26
27
|
preventStagingReplacement?: boolean;
|
|
27
28
|
dialog: ChaynsReactValues["dialog"];
|
|
28
29
|
styleSettings?: ChaynsReactValues["styleSettings"];
|
|
30
|
+
/** History layer to provide to hosted children. Defaults to the root layer. */
|
|
31
|
+
historyLayer?: ChaynsHistoryLayer;
|
|
32
|
+
/**
|
|
33
|
+
* ID for this module's dedicated child history layer.
|
|
34
|
+
* When set, a child layer with this ID is created (or reused) from the parent
|
|
35
|
+
* `historyLayer` and passed to the module — giving the module its own routing
|
|
36
|
+
* namespace. Activate it with `layer.navigate({ activeChild: historyChildId })`.
|
|
37
|
+
*/
|
|
38
|
+
historyChildId?: string;
|
|
39
|
+
/** Whether the history is disabled for the children */
|
|
40
|
+
isHistoryDisabled?: boolean;
|
|
29
41
|
} & ({
|
|
30
42
|
type: `${'client' | 'server'}-iframe`;
|
|
31
43
|
src: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { FC } from 'react';
|
|
2
2
|
import { ChaynsApiDevice, ChaynsApiSite, ChaynsApiUser, ChaynsReactFunctions, ChaynsReactValues, IChaynsReact, Page } from '../../types/IChaynsReact';
|
|
3
|
+
import type { ChaynsHistoryLayer } from '../../types/history';
|
|
3
4
|
type HostIframeProps = {
|
|
4
5
|
iFrameProps: {
|
|
5
6
|
[key: string]: unknown;
|
|
@@ -23,6 +24,9 @@ type HostIframeProps = {
|
|
|
23
24
|
preventStagingReplacement?: boolean;
|
|
24
25
|
dialog: ChaynsReactValues["dialog"];
|
|
25
26
|
styleSettings: ChaynsReactValues["styleSettings"];
|
|
27
|
+
historyLayer?: ChaynsHistoryLayer;
|
|
28
|
+
/** Whether the history is disabled for the children */
|
|
29
|
+
isHistoryDisabled?: boolean;
|
|
26
30
|
};
|
|
27
31
|
declare const HostIframe: FC<HostIframeProps>;
|
|
28
32
|
export default HostIframe;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FC, ReactNode } from 'react';
|
|
2
2
|
import { ChaynsApiDevice, ChaynsApiSite, ChaynsApiUser, ChaynsReactFunctions, ChaynsReactValues, IChaynsReact, Page } from '../../types/IChaynsReact';
|
|
3
|
+
import type { ChaynsHistoryLayer } from '../../types/history';
|
|
3
4
|
export type TypeSystem = {
|
|
4
5
|
scope: string;
|
|
5
6
|
url: string;
|
|
@@ -25,6 +26,9 @@ type ModulePropTypes = {
|
|
|
25
26
|
dialog: ChaynsReactValues["dialog"];
|
|
26
27
|
children?: ReactNode;
|
|
27
28
|
styleSettings: ChaynsReactValues["styleSettings"];
|
|
29
|
+
historyLayer?: ChaynsHistoryLayer;
|
|
30
|
+
/** Whether the history is disabled for the children */
|
|
31
|
+
isHistoryDisabled?: boolean;
|
|
28
32
|
};
|
|
29
33
|
declare const ModuleHost: FC<ModulePropTypes>;
|
|
30
34
|
export default ModuleHost;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,21 +1,30 @@
|
|
|
1
1
|
export { default as ChaynsProvider, type ChaynsProviderProps } from './components/ChaynsProvider';
|
|
2
|
-
export { default as getDeviceInfo, getScreenSize, getClientDeviceInfo } from './
|
|
2
|
+
export { default as getDeviceInfo, getScreenSize, getClientDeviceInfo } from './utils/deviceHelper';
|
|
3
3
|
export { default as ChaynsHost } from './host/ChaynsHost';
|
|
4
4
|
export { withCompatMode } from './components/withCompatMode';
|
|
5
5
|
export * from './calls';
|
|
6
6
|
export * from './hooks';
|
|
7
7
|
export * from './components/WaitUntil';
|
|
8
8
|
export * from './types/IChaynsReact';
|
|
9
|
-
export * from './
|
|
9
|
+
export * from './types/history';
|
|
10
|
+
export * from './utils/is';
|
|
10
11
|
export * from './constants';
|
|
11
12
|
export { default as withHydrationBoundary } from './components/withHydrationBoundary';
|
|
12
13
|
export { default as StaticChaynsApi } from './wrapper/StaticChaynsApi';
|
|
13
14
|
export { default as loadComponent, loadModule } from './host/module/utils/loadComponent';
|
|
14
15
|
export { default as DialogHandler } from './handler/DialogHandler';
|
|
16
|
+
export * from './handler/history';
|
|
17
|
+
export { initRootChaynsHistoryLayer, getOrInitRootChaynsHistoryLayer, type InitRootChaynsHistoryLayerOptions, type InitRootChaynsHistoryLayerResult } from './utils/history/rootLayer';
|
|
18
|
+
export { NavigationQueue } from './utils/history/NavigationQueue';
|
|
19
|
+
export { BlockRegistry } from './utils/history/BlockRegistry';
|
|
20
|
+
export { projectToUrl, parseFromUrl } from './utils/history/url';
|
|
21
|
+
export { projectToState, applyStateToTree, diffIncomingState, hasChaynsHistoryState } from './utils/history/stateProjector';
|
|
22
|
+
export { getChaynsHistoryActiveChain, findChaynsHistoryLayerById, isInChaynsHistoryActiveChain } from './utils/history/layerTree';
|
|
15
23
|
export * as dialog from './calls/dialogs/index';
|
|
16
24
|
export * from './plugins';
|
|
17
|
-
export * from './
|
|
18
|
-
export * from './
|
|
19
|
-
export * from './
|
|
20
|
-
export * from './
|
|
25
|
+
export * from './utils/initModuleFederationSharing';
|
|
26
|
+
export * from './utils/bindChaynsApi';
|
|
27
|
+
export * from './utils/appStorage';
|
|
28
|
+
export * from './utils/collectCssChunks';
|
|
29
|
+
export * from './contexts';
|
|
21
30
|
export { getChaynsApi } from './components/moduleWrapper';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { IBrowser, IEngine } from 'ua-parser-js';
|
|
2
2
|
import DialogHandler from '../handler/DialogHandler';
|
|
3
3
|
import { DialogButtonOld, SelectDialogItem } from './dialog';
|
|
4
|
+
import type { ChaynsHistoryLayer } from './history';
|
|
4
5
|
export type DialogButton = {
|
|
5
6
|
type: DialogButtonType;
|
|
6
7
|
text: string;
|
|
@@ -311,6 +312,7 @@ export interface ChaynsReactValues {
|
|
|
311
312
|
site: ChaynsApiSite;
|
|
312
313
|
user: ChaynsApiUser | undefined;
|
|
313
314
|
isAdminModeActive: boolean;
|
|
315
|
+
isHistoryDisabled?: boolean;
|
|
314
316
|
pages: Page[];
|
|
315
317
|
currentPage: {
|
|
316
318
|
id: number;
|
|
@@ -465,6 +467,7 @@ export interface ChaynsReactFunctions {
|
|
|
465
467
|
destination: string;
|
|
466
468
|
isPermanent?: boolean;
|
|
467
469
|
}) => Promise<void>;
|
|
470
|
+
getHistoryLayer(): ChaynsHistoryLayer;
|
|
468
471
|
}
|
|
469
472
|
export type ChaynsReactCustomFunctions = {
|
|
470
473
|
[key: string]: (...args: any[]) => Promise<any>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export type ChaynsHistoryNavigationCommitOptions = {
|
|
2
|
+
isReplace?: boolean;
|
|
3
|
+
};
|
|
4
|
+
export type ChaynsHistoryNavigateOptions = ChaynsHistoryNavigationCommitOptions & {
|
|
5
|
+
/** Query parameters to set on this layer. Replaces existing params for this layer. */
|
|
6
|
+
params?: Record<string, string>;
|
|
7
|
+
/** URL hash fragment (without leading `#`). Pass `''` to explicitly clear. */
|
|
8
|
+
hash?: string;
|
|
9
|
+
};
|
|
10
|
+
export type ChaynsHistoryBlockOptions = {
|
|
11
|
+
/** @default 'local' */
|
|
12
|
+
scope?: 'local' | 'global';
|
|
13
|
+
/** @default false */
|
|
14
|
+
isBeforeUnload?: boolean;
|
|
15
|
+
};
|
|
16
|
+
export type ChaynsHistoryLayerEvent = {
|
|
17
|
+
type: 'change' | 'popstate';
|
|
18
|
+
layerId: string;
|
|
19
|
+
segments: string[];
|
|
20
|
+
state: Record<string, unknown>;
|
|
21
|
+
params: Record<string, string>;
|
|
22
|
+
hash: string;
|
|
23
|
+
};
|
|
24
|
+
export type ChaynsHistoryActionResult = {
|
|
25
|
+
isOk: true;
|
|
26
|
+
} | {
|
|
27
|
+
isOk: false;
|
|
28
|
+
reason: 'blocked' | 'stale' | 'destroyed' | 'error';
|
|
29
|
+
error?: unknown;
|
|
30
|
+
};
|
|
31
|
+
export type ChaynsHistoryLayerStateNode = {
|
|
32
|
+
activeChild?: string;
|
|
33
|
+
childState?: ChaynsHistoryLayerStateNode;
|
|
34
|
+
/** @internal Reserved — managed by history core. */
|
|
35
|
+
__params?: Record<string, string>;
|
|
36
|
+
/** @internal Reserved — managed by history core. `undefined` = unset, `''` = explicit clear. */
|
|
37
|
+
__hash?: string;
|
|
38
|
+
[key: string]: unknown;
|
|
39
|
+
};
|
|
40
|
+
export interface ChaynsHistoryLayer {
|
|
41
|
+
readonly id: string;
|
|
42
|
+
readonly depth: number;
|
|
43
|
+
getSegmentCount(): number;
|
|
44
|
+
setSegmentCount(n: number): void;
|
|
45
|
+
createChildLayer(id: string): ChaynsHistoryLayer;
|
|
46
|
+
destroyChildLayer(id: string): void;
|
|
47
|
+
setActiveChild(id: string | null, init?: {
|
|
48
|
+
route?: string | string[];
|
|
49
|
+
state?: Record<string, unknown>;
|
|
50
|
+
}): Promise<ChaynsHistoryActionResult>;
|
|
51
|
+
getActiveChildId(): string | null;
|
|
52
|
+
getChildLayer(id: string): ChaynsHistoryLayer | undefined;
|
|
53
|
+
getRoute(): string[];
|
|
54
|
+
setRoute(route: string | string[], opts?: ChaynsHistoryNavigateOptions): void;
|
|
55
|
+
getParams(): Record<string, string>;
|
|
56
|
+
setParams(params: Record<string, string>, opts?: ChaynsHistoryNavigationCommitOptions): void;
|
|
57
|
+
getHash(): string;
|
|
58
|
+
setHash(hash: string, opts?: ChaynsHistoryNavigationCommitOptions): void;
|
|
59
|
+
getState<T extends object = Record<string, unknown>>(): T | undefined;
|
|
60
|
+
setState<T extends object>(state: T, opts?: ChaynsHistoryNavigateOptions): void;
|
|
61
|
+
navigate(opts: {
|
|
62
|
+
route?: string | string[];
|
|
63
|
+
state?: Record<string, unknown>;
|
|
64
|
+
/** Switch the active child as part of this navigation. Auto-creates the child if needed. */
|
|
65
|
+
activeChild?: string | null;
|
|
66
|
+
/** Initial route/state to seed the child with when it is first activated. */
|
|
67
|
+
activeChildInit?: {
|
|
68
|
+
route?: string | string[];
|
|
69
|
+
state?: Record<string, unknown>;
|
|
70
|
+
};
|
|
71
|
+
} & ChaynsHistoryNavigateOptions): Promise<ChaynsHistoryActionResult>;
|
|
72
|
+
addBlock(callback: () => Promise<boolean>, opts?: ChaynsHistoryBlockOptions): () => void;
|
|
73
|
+
addEventListener(type: 'popstate' | 'change', handler: (e: ChaynsHistoryLayerEvent) => void): () => void;
|
|
74
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { default as getDeviceInfo, getScreenSize, getClientDeviceInfo } from './
|
|
1
|
+
export { default as getDeviceInfo, getScreenSize, getClientDeviceInfo } from './utils/deviceHelper';
|
|
2
2
|
export * from './calls';
|
|
3
3
|
export * from './types/IChaynsReact';
|
|
4
|
-
export * from './
|
|
4
|
+
export * from './utils/is';
|
|
5
5
|
export { default as StaticChaynsApi } from './wrapper/StaticChaynsApi';
|
|
6
6
|
export { default as DialogHandler } from './handler/DialogHandler';
|
|
7
7
|
export * as dialog from './calls/dialogs/index';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ChaynsHistoryLayer } from '../../handler/history/HistoryLayer';
|
|
2
|
+
import type { ChaynsHistoryBlockOptions } from '../../types/history';
|
|
3
|
+
interface BlockEntry {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly callback: () => Promise<boolean>;
|
|
6
|
+
readonly opts: Required<ChaynsHistoryBlockOptions>;
|
|
7
|
+
}
|
|
8
|
+
export declare class BlockRegistry {
|
|
9
|
+
/** Per-layer block list. */
|
|
10
|
+
private readonly layerBlocks;
|
|
11
|
+
/** Number of blocks with `isBeforeUnload: true`. When > 0, listener is attached. */
|
|
12
|
+
private beforeUnloadCount;
|
|
13
|
+
private readonly beforeUnloadHandler;
|
|
14
|
+
add(layer: ChaynsHistoryLayer, callback: () => Promise<boolean>, opts?: ChaynsHistoryBlockOptions): () => void;
|
|
15
|
+
remove(layerId: string, entry: BlockEntry): void;
|
|
16
|
+
/** Remove all blocks registered for a layer (called on destroy). */
|
|
17
|
+
removeAllForLayer(layerId: string): void;
|
|
18
|
+
/**
|
|
19
|
+
* Collects all blocks applicable to a navigation targeting `targetLayer`.
|
|
20
|
+
*
|
|
21
|
+
* Rules:
|
|
22
|
+
* - `local` blocks: only those registered on `targetLayer`.
|
|
23
|
+
* - `global` blocks: those registered on `targetLayer` or any of its
|
|
24
|
+
* **active-chain descendants** (not inactive subtrees).
|
|
25
|
+
*/
|
|
26
|
+
collectApplicableBlocks(targetLayer: ChaynsHistoryLayer): BlockEntry[];
|
|
27
|
+
private collectGlobalFromActiveDescendants;
|
|
28
|
+
/**
|
|
29
|
+
* Runs all applicable block callbacks in parallel.
|
|
30
|
+
* Returns `true` if navigation is allowed (no block), `false` otherwise.
|
|
31
|
+
* Callbacks that throw or time out count as blocked (with dev-warn).
|
|
32
|
+
*/
|
|
33
|
+
checkBlocks(targetLayer: ChaynsHistoryLayer): Promise<boolean>;
|
|
34
|
+
private runBlock;
|
|
35
|
+
private incrementBeforeUnload;
|
|
36
|
+
private decrementBeforeUnload;
|
|
37
|
+
}
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { ChaynsHistoryLayer } from '../../handler/history/HistoryLayer';
|
|
2
|
+
import type { ChaynsHistoryActionResult, ChaynsHistoryNavigateOptions, ChaynsHistoryNavigationCommitOptions } from '../../types/history';
|
|
3
|
+
export type NavOp = {
|
|
4
|
+
kind: 'setRoute';
|
|
5
|
+
layerId: string;
|
|
6
|
+
segments: string[];
|
|
7
|
+
opts: ChaynsHistoryNavigateOptions;
|
|
8
|
+
/** @internal Force a change notification even when segments appear unchanged (bootstrap via setSegmentCount). */
|
|
9
|
+
_notifyEvenIfUnchanged?: true;
|
|
10
|
+
/** @internal Notify subscribers without mutating the browser history (used for segment ownership/bootstrap updates). */
|
|
11
|
+
_skipCommit?: true;
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'setState';
|
|
14
|
+
layerId: string;
|
|
15
|
+
state: Record<string, unknown>;
|
|
16
|
+
opts: ChaynsHistoryNavigateOptions;
|
|
17
|
+
} | {
|
|
18
|
+
kind: 'setParams';
|
|
19
|
+
layerId: string;
|
|
20
|
+
params: Record<string, string>;
|
|
21
|
+
opts: ChaynsHistoryNavigationCommitOptions;
|
|
22
|
+
} | {
|
|
23
|
+
kind: 'setHash';
|
|
24
|
+
layerId: string;
|
|
25
|
+
hash: string;
|
|
26
|
+
opts: ChaynsHistoryNavigationCommitOptions;
|
|
27
|
+
} | {
|
|
28
|
+
kind: 'setActiveChild';
|
|
29
|
+
layerId: string;
|
|
30
|
+
childId: string | null;
|
|
31
|
+
init?: {
|
|
32
|
+
route?: string[];
|
|
33
|
+
state?: Record<string, unknown>;
|
|
34
|
+
};
|
|
35
|
+
} | {
|
|
36
|
+
kind: 'navigate';
|
|
37
|
+
layerId: string;
|
|
38
|
+
route?: string[];
|
|
39
|
+
state?: Record<string, unknown>;
|
|
40
|
+
params?: Record<string, string>;
|
|
41
|
+
hash?: string;
|
|
42
|
+
activeChild?: string | null;
|
|
43
|
+
activeChildInit?: {
|
|
44
|
+
route?: string[];
|
|
45
|
+
state?: Record<string, unknown>;
|
|
46
|
+
};
|
|
47
|
+
opts: ChaynsHistoryNavigationCommitOptions;
|
|
48
|
+
} | {
|
|
49
|
+
kind: 'popstate';
|
|
50
|
+
rawState: unknown;
|
|
51
|
+
};
|
|
52
|
+
export type NavResult = ChaynsHistoryActionResult;
|
|
53
|
+
export interface NavigationQueueDeps {
|
|
54
|
+
/** Returns root layer (top window only). */
|
|
55
|
+
getRoot: () => ChaynsHistoryLayer;
|
|
56
|
+
/** Find a layer by id starting at root. */
|
|
57
|
+
findLayer: (id: string) => ChaynsHistoryLayer | undefined;
|
|
58
|
+
/** Run the block check pipeline for a target layer. Returns true if free to proceed. */
|
|
59
|
+
checkBlocks: (target: ChaynsHistoryLayer) => Promise<boolean>;
|
|
60
|
+
/** Project the current memory tree into the URL string. */
|
|
61
|
+
projectUrl: () => string;
|
|
62
|
+
/** Project the current memory tree into the history state object (merged with existing foreign keys). */
|
|
63
|
+
projectState: () => Record<string, unknown>;
|
|
64
|
+
/**
|
|
65
|
+
* Compute which layer ids WOULD change without mutating the tree.
|
|
66
|
+
* Used to identify the block target before applying incoming state.
|
|
67
|
+
*/
|
|
68
|
+
diffIncomingState: (raw: unknown) => {
|
|
69
|
+
changedLayerIds: Set<string>;
|
|
70
|
+
};
|
|
71
|
+
/** Apply an incoming raw `__chaynsHistory` state onto the memory tree. Returns affected layer ids. */
|
|
72
|
+
applyIncomingState: (raw: unknown) => {
|
|
73
|
+
changedLayerIds: Set<string>;
|
|
74
|
+
};
|
|
75
|
+
/** Move history without triggering our normal popstate handling (used to undo blocked navigations). */
|
|
76
|
+
silentGo: (delta: number) => Promise<void>;
|
|
77
|
+
/** Returns the current navigation index (incremented on every push). */
|
|
78
|
+
getCurrentIdx: () => number;
|
|
79
|
+
/** Increments the navigation index and returns the new value. */
|
|
80
|
+
incrementIdx: () => number;
|
|
81
|
+
/**
|
|
82
|
+
* Re-parse segments from `window.location.pathname` and apply them to each
|
|
83
|
+
* layer in the active chain based on its `segmentCount`. Called after
|
|
84
|
+
* `applyIncomingState` so the active chain reflects the new `activeChild`.
|
|
85
|
+
* Returns the ids of layers whose segments actually changed.
|
|
86
|
+
*/
|
|
87
|
+
applyUrlSegments: () => {
|
|
88
|
+
changedLayerIds: Set<string>;
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
export declare class NavigationQueue {
|
|
92
|
+
private readonly queue;
|
|
93
|
+
private isRunning;
|
|
94
|
+
private readonly deps;
|
|
95
|
+
constructor(deps: NavigationQueueDeps);
|
|
96
|
+
enqueue(op: NavOp): Promise<NavResult>;
|
|
97
|
+
private tick;
|
|
98
|
+
private process;
|
|
99
|
+
private processSetRoute;
|
|
100
|
+
private processSetParams;
|
|
101
|
+
private processSetHash;
|
|
102
|
+
private processSetState;
|
|
103
|
+
private processSetActiveChild;
|
|
104
|
+
private processNavigate;
|
|
105
|
+
private processPopstate;
|
|
106
|
+
private resolveActiveLayer;
|
|
107
|
+
private resolveLowestCommonLayer;
|
|
108
|
+
private commit;
|
|
109
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ChaynsHistoryLayer } from '../../handler/history/HistoryLayer';
|
|
2
|
+
/**
|
|
3
|
+
* Returns the ordered chain of layers from root to the deepest active layer
|
|
4
|
+
* (inclusive of root).
|
|
5
|
+
*/
|
|
6
|
+
export declare function getChaynsHistoryActiveChain(root: ChaynsHistoryLayer): ChaynsHistoryLayer[];
|
|
7
|
+
/** Depth-first search for a layer by id starting at `root`. */
|
|
8
|
+
export declare function findChaynsHistoryLayerById(root: ChaynsHistoryLayer, id: string): ChaynsHistoryLayer | undefined;
|
|
9
|
+
/** Returns true if the layer is reachable via active children from the root. */
|
|
10
|
+
export declare function isInChaynsHistoryActiveChain(layer: ChaynsHistoryLayer): boolean;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Increment the current index (call on every real pushState). Returns the new value. */
|
|
2
|
+
export declare function incrementIdx(): number;
|
|
3
|
+
/** Get current index for stamping real entries or direction comparison. */
|
|
4
|
+
export declare function getCurrentIdx(): number;
|
|
5
|
+
/**
|
|
6
|
+
* Performs a `history.go(delta)` that is silently ignored by our popstate handler.
|
|
7
|
+
* Returns a promise that resolves when the popstate for this go() fires.
|
|
8
|
+
*/
|
|
9
|
+
export declare function silentGo(delta: number): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Called by the popstate handler. Returns true if this popstate is the silent one
|
|
12
|
+
* and should be suppressed.
|
|
13
|
+
*/
|
|
14
|
+
export declare function consumeSilent(): boolean;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ChaynsHistoryLayer } from '../../handler/history/HistoryLayer';
|
|
2
|
+
/** Parses the URL into a flat segment array and returns all entries after the first `startIndex` entries. */
|
|
3
|
+
export declare function resolveSegmentsFrom(overrideUrl: string | undefined, startIndex: number): string[];
|
|
4
|
+
export interface InitRootChaynsHistoryLayerOptions {
|
|
5
|
+
/**
|
|
6
|
+
* The current page URL used to seed initial route segments.
|
|
7
|
+
* - **Browser**: defaults to `window.location.pathname` — no need to set this.
|
|
8
|
+
* - **SSR**: pass the request URL (e.g. `req.url` or `router.asPath`) so
|
|
9
|
+
* child layers receive the correct initial segments on the server.
|
|
10
|
+
*/
|
|
11
|
+
url?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Number of URL path segments the root layer owns.
|
|
14
|
+
* When provided, segments are resolved from the URL immediately at construction
|
|
15
|
+
* so that `getRoute()` is populated on the very first render.
|
|
16
|
+
*/
|
|
17
|
+
segmentCount?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface InitRootChaynsHistoryLayerResult {
|
|
20
|
+
rootLayer: ChaynsHistoryLayer;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Initializes the root ChaynsHistoryLayer for the top window.
|
|
24
|
+
* - Reads `window.location.pathname` and `window.history.state`.
|
|
25
|
+
* - If `__chaynsHistory` is absent, replaces the current state with an empty tree.
|
|
26
|
+
* - Attaches the global `popstate` listener.
|
|
27
|
+
* - Returns the root ChaynsHistoryLayer instance.
|
|
28
|
+
*
|
|
29
|
+
* Call once at application startup (top window only).
|
|
30
|
+
*/
|
|
31
|
+
export declare function initRootChaynsHistoryLayer(opts?: InitRootChaynsHistoryLayerOptions): InitRootChaynsHistoryLayerResult;
|
|
32
|
+
/**
|
|
33
|
+
* Returns the singleton root ChaynsHistoryLayer for the current window.
|
|
34
|
+
* Creates it on first call; subsequent calls return the same instance.
|
|
35
|
+
*
|
|
36
|
+
* @param url - On SSR, pass the current request URL (e.g. `req.url` or `router.asPath`)
|
|
37
|
+
* so child layers receive the correct initial route segments. Ignored after first call.
|
|
38
|
+
* @param segmentCount - Number of URL segments the root layer owns. When provided the
|
|
39
|
+
* segments are resolved from the URL immediately so `getRoute()` is populated on the
|
|
40
|
+
* very first render without any subsequent `setSegmentCount` call. Ignored after first call.
|
|
41
|
+
*/
|
|
42
|
+
export declare function getOrInitRootChaynsHistoryLayer(url?: string, segmentCount?: number): InitRootChaynsHistoryLayerResult;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ChaynsHistoryLayer } from '../../handler/history/HistoryLayer';
|
|
2
|
+
import type { ChaynsHistoryLayerStateNode } from '../../types/history';
|
|
3
|
+
/**
|
|
4
|
+
* Returns the value to store in `window.history.state`, merging with any
|
|
5
|
+
* pre-existing foreign keys so we never overwrite other consumers' state.
|
|
6
|
+
*/
|
|
7
|
+
export declare function projectToState(root: ChaynsHistoryLayer, existing?: Record<string, unknown>): Record<string, unknown>;
|
|
8
|
+
/**
|
|
9
|
+
* Applies the raw `window.history.state` payload onto the layer tree.
|
|
10
|
+
* Returns the set of layer ids whose segments OR ownState changed.
|
|
11
|
+
*/
|
|
12
|
+
export declare function applyStateToTree(root: ChaynsHistoryLayer, raw: unknown): {
|
|
13
|
+
changedLayerIds: Set<string>;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Like `applyStateToTree` but does NOT mutate the tree.
|
|
17
|
+
* Returns layer ids that WOULD change if the state were applied.
|
|
18
|
+
*/
|
|
19
|
+
export declare function diffIncomingState(root: ChaynsHistoryLayer, raw: unknown): {
|
|
20
|
+
changedLayerIds: Set<string>;
|
|
21
|
+
};
|
|
22
|
+
declare function extractNode(raw: unknown): ChaynsHistoryLayerStateNode | null;
|
|
23
|
+
export { extractNode as _extractNode };
|
|
24
|
+
export declare function hasChaynsHistoryState(raw: unknown): boolean;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ChaynsHistoryLayer } from '../../handler/history/HistoryLayer';
|
|
2
|
+
/**
|
|
3
|
+
* Concatenates all segments along the active chain into a URL with pathname,
|
|
4
|
+
* merged query params, and the deepest explicitly-set hash.
|
|
5
|
+
*/
|
|
6
|
+
export declare function projectToUrl(root: ChaynsHistoryLayer): string;
|
|
7
|
+
export interface ParseResult {
|
|
8
|
+
/** Maps layer id → segments assigned to that layer. */
|
|
9
|
+
perLayerSegments: Map<string, string[]>;
|
|
10
|
+
/** Segments that could not be assigned to any layer's segmentCount. */
|
|
11
|
+
pendingSegments: string[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Splits the incoming URL pathname onto layers based on each layer's `segmentCount`.
|
|
15
|
+
* Traverses the active chain; excess segments go to `pendingSegments`.
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseFromUrl(url: string, root: ChaynsHistoryLayer): ParseResult;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function hasWindowHistory(): boolean;
|
|
@@ -64,6 +64,7 @@ declare class StaticChaynsApi implements ChaynsReactFunctions {
|
|
|
64
64
|
addAccessTokenChangeListener: ChaynsReactFunctions['addAccessTokenChangeListener'];
|
|
65
65
|
removeAccessTokenChangeListener: ChaynsReactFunctions['removeAccessTokenChangeListener'];
|
|
66
66
|
redirect: ChaynsReactFunctions['redirect'];
|
|
67
|
+
getHistoryLayer: ChaynsReactFunctions['getHistoryLayer'];
|
|
67
68
|
ready: Promise<void>;
|
|
68
69
|
addDataListener: (cb: DataChangeCallback) => () => void;
|
|
69
70
|
private _wrapper;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chayns-api",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.0-beta.0",
|
|
4
4
|
"description": "new chayns api",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -74,6 +74,7 @@
|
|
|
74
74
|
"chayns-toolkit": "^4.0.0-beta.0",
|
|
75
75
|
"concurrently": "^9.2.1",
|
|
76
76
|
"cross-env": "^10.1.0",
|
|
77
|
+
"jsdom": "^29.1.1",
|
|
77
78
|
"prettier": "^3.7.4",
|
|
78
79
|
"prettier-plugin-packagejson": "^2.5.20",
|
|
79
80
|
"react": "^18.3.1",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|