@flemo/core 1.0.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.
Files changed (36) hide show
  1. package/LICENSE +21 -0
  2. package/dist/core/TaskManger.d.ts +62 -0
  3. package/dist/core/__tests__/TaskManger.test.d.ts +1 -0
  4. package/dist/history/__tests__/store.test.d.ts +1 -0
  5. package/dist/history/store.d.ts +17 -0
  6. package/dist/index.d.ts +23 -0
  7. package/dist/index.mjs +965 -0
  8. package/dist/navigate/__tests__/selfPopGuard.test.d.ts +1 -0
  9. package/dist/navigate/selfPopGuard.d.ts +12 -0
  10. package/dist/navigate/store.d.ts +9 -0
  11. package/dist/transition/__tests__/compileTransitionStyles.test.d.ts +7 -0
  12. package/dist/transition/compileTransitionStyles.d.ts +13 -0
  13. package/dist/transition/createRawTransition.d.ts +18 -0
  14. package/dist/transition/createTransition.d.ts +14 -0
  15. package/dist/transition/cssTypes.d.ts +22 -0
  16. package/dist/transition/cupertino.d.ts +2 -0
  17. package/dist/transition/decorator/createDecorator.d.ts +12 -0
  18. package/dist/transition/decorator/createRawDecorator.d.ts +19 -0
  19. package/dist/transition/decorator/decorator.d.ts +2 -0
  20. package/dist/transition/decorator/overlay.d.ts +2 -0
  21. package/dist/transition/decorator/typing.d.ts +24 -0
  22. package/dist/transition/layout.d.ts +2 -0
  23. package/dist/transition/material.d.ts +2 -0
  24. package/dist/transition/none.d.ts +2 -0
  25. package/dist/transition/store.d.ts +7 -0
  26. package/dist/transition/transition.d.ts +2 -0
  27. package/dist/transition/typing.d.ts +61 -0
  28. package/dist/utils/__tests__/findScrollable.test.d.ts +1 -0
  29. package/dist/utils/__tests__/getMatchedPathPattern.test.d.ts +1 -0
  30. package/dist/utils/__tests__/getParams.test.d.ts +1 -0
  31. package/dist/utils/__tests__/isServer.test.d.ts +1 -0
  32. package/dist/utils/findScrollable.d.ts +21 -0
  33. package/dist/utils/getMatchedPathPattern.d.ts +2 -0
  34. package/dist/utils/getParams.d.ts +4 -0
  35. package/dist/utils/isServer.d.ts +1 -0
  36. package/package.json +62 -0
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Marks that flemo itself is about to call `window.history.back()`. The
3
+ * `popstate` it produces is then consumed by `consumeSelfInducedPop` so the
4
+ * popstate listener doesn't re-process a pop the navigation queue already owns.
5
+ */
6
+ export declare function markSelfInducedPop(): void;
7
+ /**
8
+ * Returns `true` once for each prior `markSelfInducedPop` call, balancing
9
+ * flemo-initiated `history.back()` calls against incoming `popstate` events.
10
+ * A genuine browser back/forward press is the event that overflows the count.
11
+ */
12
+ export declare function consumeSelfInducedPop(): boolean;
@@ -0,0 +1,9 @@
1
+ export type NavigateStatus = "IDLE" | "PUSHING" | "REPLACING" | "POPPING" | "COMPLETED";
2
+ interface NavigateStore {
3
+ status: NavigateStatus;
4
+ transitionTaskId: string | null;
5
+ setStatus: (status: NavigateStatus) => void;
6
+ setTransitionTaskId: (transitionTaskId: string | null) => void;
7
+ }
8
+ declare const useNavigateStore: import('zustand').UseBoundStore<import('zustand').StoreApi<NavigateStore>>;
9
+ export default useNavigateStore;
@@ -0,0 +1,7 @@
1
+ declare module '../typing' {
2
+ interface RegisterTransition {
3
+ "custom-fade-blur": "custom-fade-blur";
4
+ "custom-slide-fade": "custom-slide-fade";
5
+ }
6
+ }
7
+ export {};
@@ -0,0 +1,13 @@
1
+ import { AnimationOptions, InitialTarget } from './cssTypes';
2
+ import { Transition, TransitionVariant, TransitionVariantValue } from './typing';
3
+ import { Decorator } from './decorator/typing';
4
+ export type CssDecl = {
5
+ property: string;
6
+ value: string;
7
+ };
8
+ export declare const collectAnimatedProperties: (transition: Transition) => string[];
9
+ export declare const targetToDecls: (target: TransitionVariantValue["value"] | InitialTarget) => CssDecl[];
10
+ export declare const easingToCss: (ease: AnimationOptions["ease"] | undefined) => string;
11
+ export declare const animationName: (scope: "screen" | "decorator", name: string, variant: TransitionVariant) => string;
12
+ export declare const compileTransitionStyles: (transitions: Iterable<Transition>, decorators: Iterable<Decorator>) => string;
13
+ export declare const variantHasAnimation: (transitionLike: Pick<Transition, "initial" | "variants">, variant: TransitionVariant) => boolean;
@@ -0,0 +1,18 @@
1
+ import { InitialTarget } from './cssTypes';
2
+ import { TransitionOptions, Transition, TransitionVariantValue, TransitionName } from './typing';
3
+ interface CreateRawTransitionProps {
4
+ name: TransitionName;
5
+ initial: InitialTarget;
6
+ idle: TransitionVariantValue;
7
+ pushOnEnter: TransitionVariantValue;
8
+ pushOnExit: TransitionVariantValue;
9
+ replaceOnEnter: TransitionVariantValue;
10
+ replaceOnExit: TransitionVariantValue;
11
+ popOnEnter: TransitionVariantValue;
12
+ popOnExit: TransitionVariantValue;
13
+ completedOnEnter: TransitionVariantValue;
14
+ completedOnExit: TransitionVariantValue;
15
+ options?: TransitionOptions;
16
+ }
17
+ export default function createRawTransition({ name, initial, idle, pushOnEnter, pushOnExit, replaceOnEnter, replaceOnExit, popOnEnter, popOnExit, completedOnExit, completedOnEnter, options }: CreateRawTransitionProps): Transition;
18
+ export {};
@@ -0,0 +1,14 @@
1
+ import { InitialTarget } from './cssTypes';
2
+ import { TransitionOptions, Transition, TransitionVariantValue, TransitionName } from './typing';
3
+ interface CreateTransitionProps {
4
+ name: TransitionName;
5
+ initial: InitialTarget;
6
+ idle: TransitionVariantValue;
7
+ enter: TransitionVariantValue;
8
+ enterBack: TransitionVariantValue;
9
+ exit: TransitionVariantValue;
10
+ exitBack: TransitionVariantValue;
11
+ options?: TransitionOptions;
12
+ }
13
+ export default function createTransition({ name, initial, idle, enter, enterBack, exit, exitBack, options }: CreateTransitionProps): Transition;
14
+ export {};
@@ -0,0 +1,22 @@
1
+ export type AnimationEasing = string | readonly [number, number, number, number] | [number, number, number, number];
2
+ export interface AnimationOptions {
3
+ duration?: number;
4
+ ease?: AnimationEasing;
5
+ delay?: number;
6
+ }
7
+ export interface TransitionTarget {
8
+ x?: string | number;
9
+ y?: string | number;
10
+ z?: string | number;
11
+ scale?: string | number;
12
+ scaleX?: string | number;
13
+ scaleY?: string | number;
14
+ rotate?: string | number;
15
+ rotateX?: string | number;
16
+ rotateY?: string | number;
17
+ rotateZ?: string | number;
18
+ opacity?: number | string;
19
+ backgroundColor?: string;
20
+ [key: string]: string | number | undefined;
21
+ }
22
+ export type InitialTarget = TransitionTarget;
@@ -0,0 +1,2 @@
1
+ declare const cupertino: import('./typing').Transition;
2
+ export default cupertino;
@@ -0,0 +1,12 @@
1
+ import { InitialTarget } from '../cssTypes';
2
+ import { TransitionVariantValue } from '../typing';
3
+ import { DecoratorName, Decorator, DecoratorOptions } from './typing';
4
+ interface CreateDecoratorProps {
5
+ name: DecoratorName;
6
+ initial: InitialTarget;
7
+ enter: TransitionVariantValue;
8
+ exit: TransitionVariantValue;
9
+ options?: DecoratorOptions;
10
+ }
11
+ export default function createDecorator({ name, initial, enter, exit, options }: CreateDecoratorProps): Decorator;
12
+ export {};
@@ -0,0 +1,19 @@
1
+ import { InitialTarget } from '../cssTypes';
2
+ import { TransitionVariantValue } from '../typing';
3
+ import { DecoratorName, Decorator, DecoratorOptions } from './typing';
4
+ interface CreateRawDecoratorProps {
5
+ name: DecoratorName;
6
+ initial: InitialTarget;
7
+ idle: TransitionVariantValue;
8
+ pushOnEnter: TransitionVariantValue;
9
+ pushOnExit: TransitionVariantValue;
10
+ replaceOnEnter: TransitionVariantValue;
11
+ replaceOnExit: TransitionVariantValue;
12
+ popOnEnter: TransitionVariantValue;
13
+ popOnExit: TransitionVariantValue;
14
+ completedOnEnter: TransitionVariantValue;
15
+ completedOnExit: TransitionVariantValue;
16
+ options?: DecoratorOptions;
17
+ }
18
+ export default function createRawDecorator({ name, initial, idle, pushOnEnter, pushOnExit, replaceOnEnter, replaceOnExit, popOnEnter, popOnExit, completedOnEnter, completedOnExit, options }: CreateRawDecoratorProps): Decorator;
19
+ export {};
@@ -0,0 +1,2 @@
1
+ import { Decorator } from './typing';
2
+ export declare const decoratorMap: Map<"overlay", Decorator>;
@@ -0,0 +1,2 @@
1
+ declare const overlay: import('./typing').Decorator;
2
+ export default overlay;
@@ -0,0 +1,24 @@
1
+ import { BaseTransition, SwipeAnimate } from '../typing';
2
+ export interface RegisterDecorator {
3
+ }
4
+ export type DecoratorName = RegisterDecorator[keyof RegisterDecorator] | "overlay";
5
+ export type DecoratorOptions = {
6
+ onSwipeStart?: (triggered: boolean, options: {
7
+ animate: SwipeAnimate;
8
+ currentDecorator: HTMLDivElement;
9
+ prevDecorator: HTMLDivElement;
10
+ }) => void;
11
+ onSwipe?: (triggered: boolean, progress: number, options: {
12
+ animate: SwipeAnimate;
13
+ currentDecorator: HTMLDivElement;
14
+ prevDecorator: HTMLDivElement;
15
+ }) => void;
16
+ onSwipeEnd?: (triggered: boolean, options: {
17
+ animate: SwipeAnimate;
18
+ currentDecorator: HTMLDivElement;
19
+ prevDecorator: HTMLDivElement;
20
+ }) => void;
21
+ };
22
+ export interface Decorator extends Omit<BaseTransition, "name">, DecoratorOptions {
23
+ name: DecoratorName;
24
+ }
@@ -0,0 +1,2 @@
1
+ declare const layout: import('./typing').Transition;
2
+ export default layout;
@@ -0,0 +1,2 @@
1
+ declare const material: import('./typing').Transition;
2
+ export default material;
@@ -0,0 +1,2 @@
1
+ declare const none: import('./typing').Transition;
2
+ export default none;
@@ -0,0 +1,7 @@
1
+ import { TransitionName } from './typing';
2
+ interface TransitionStore {
3
+ defaultTransitionName: TransitionName;
4
+ setDefaultTransitionName: (defaultTransitionName: TransitionName) => void;
5
+ }
6
+ declare const useTransitionStore: import('zustand').UseBoundStore<import('zustand').StoreApi<TransitionStore>>;
7
+ export default useTransitionStore;
@@ -0,0 +1,2 @@
1
+ import { TransitionName, Transition } from './typing';
2
+ export declare const transitionMap: Map<TransitionName, Transition>;
@@ -0,0 +1,61 @@
1
+ import { NavigateStatus } from '../navigate/store';
2
+ import { AnimationOptions, InitialTarget, TransitionTarget } from './cssTypes';
3
+ import { DecoratorName } from './decorator/typing';
4
+ export interface RegisterTransition {
5
+ }
6
+ export type TransitionName = RegisterTransition[keyof RegisterTransition] | "none" | "cupertino" | "material" | "layout";
7
+ export type TransitionVariant = `${NavigateStatus}-${boolean}`;
8
+ export type TransitionVariantValue = {
9
+ value: TransitionTarget;
10
+ options: AnimationOptions;
11
+ };
12
+ export interface SwipeInfo {
13
+ point: {
14
+ x: number;
15
+ y: number;
16
+ };
17
+ offset: {
18
+ x: number;
19
+ y: number;
20
+ };
21
+ velocity: {
22
+ x: number;
23
+ y: number;
24
+ };
25
+ delta: {
26
+ x: number;
27
+ y: number;
28
+ };
29
+ }
30
+ export type SwipeAnimate = (target: HTMLElement, value: TransitionTarget, options?: AnimationOptions) => Promise<void>;
31
+ export type TransitionOptions = {
32
+ decoratorName?: DecoratorName;
33
+ swipeDirection: "x" | "y";
34
+ onSwipeStart: (event: PointerEvent, info: SwipeInfo, options: {
35
+ animate: SwipeAnimate;
36
+ currentScreen: HTMLDivElement;
37
+ prevScreen: HTMLDivElement;
38
+ onStart?: (triggered: boolean) => void;
39
+ }) => Promise<boolean>;
40
+ onSwipe: (event: PointerEvent, info: SwipeInfo, options: {
41
+ animate: SwipeAnimate;
42
+ currentScreen: HTMLDivElement;
43
+ prevScreen: HTMLDivElement;
44
+ onProgress?: (triggered: boolean, progress: number) => void;
45
+ }) => number;
46
+ onSwipeEnd: (event: PointerEvent, info: SwipeInfo, options: {
47
+ animate: SwipeAnimate;
48
+ currentScreen: HTMLDivElement;
49
+ prevScreen: HTMLDivElement;
50
+ onStart?: (triggered: boolean) => void;
51
+ }) => Promise<boolean>;
52
+ } | {
53
+ decoratorName?: DecoratorName;
54
+ swipeDirection?: never;
55
+ };
56
+ export interface BaseTransition {
57
+ name: TransitionName;
58
+ initial: InitialTarget;
59
+ variants: Record<TransitionVariant, TransitionVariantValue>;
60
+ }
61
+ export type Transition = BaseTransition & TransitionOptions;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ export default function findScrollable(startTarget: EventTarget | null, options?: {
2
+ direction?: "y" | "x";
3
+ markerSelector?: string;
4
+ depthLimit?: number;
5
+ verifyByScroll?: boolean;
6
+ }): {
7
+ element: HTMLElement | null;
8
+ hasMarker: boolean;
9
+ };
10
+ /** Whether the element's content overflows the given axis (sub-pixel safe). */
11
+ export declare function overflowsAxis(element: HTMLElement, direction: "y" | "x"): boolean;
12
+ /**
13
+ * Whether the element actually scrolls on the given axis.
14
+ *
15
+ * Reads `overflowX` / `overflowY` from computed style — fast, read-only,
16
+ * and free of side effects. The previous implementation probed by writing
17
+ * to `scrollTop` / `scrollLeft` and reverting, which fired scroll events
18
+ * and interfered with `scroll-snap` / `scroll-behavior: smooth` consumers
19
+ * on every pointerdown that flowed through `findScrollable`.
20
+ */
21
+ export declare function canProgrammaticallyScroll(element: HTMLElement, direction: "y" | "x"): boolean;
@@ -0,0 +1,2 @@
1
+ import { Path } from 'path-to-regexp';
2
+ export default function getMatchedPathPattern(paths: Path | Path[], pathname: string): Path;
@@ -0,0 +1,4 @@
1
+ import { Path } from 'path-to-regexp';
2
+ export default function getParams(paths: Path | Path[], path: string, search: string): {
3
+ [x: string]: string;
4
+ };
@@ -0,0 +1 @@
1
+ export default function isServer(): boolean;
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@flemo/core",
3
+ "version": "1.0.0",
4
+ "description": "Framework-agnostic primitives for flemo: history, navigation, transitions, task manager.",
5
+ "main": "./dist/index.mjs",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "type": "module",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "sideEffects": false,
13
+ "keywords": [
14
+ "flemo",
15
+ "router",
16
+ "transition",
17
+ "framework-agnostic"
18
+ ],
19
+ "author": {
20
+ "name": "kimjh96",
21
+ "email": "kimjhs@kakao.com"
22
+ },
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/kimjh96/flemo.git",
26
+ "directory": "packages/flemo-core"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/kimjh96/flemo/issues",
30
+ "email": "kimjhs@kakao.com"
31
+ },
32
+ "homepage": "https://flemo-web.vercel.app",
33
+ "license": "MIT",
34
+ "dependencies": {
35
+ "path-to-regexp": "^8.2.0",
36
+ "zustand": "^5.0.11"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^24.3.0",
40
+ "eslint": "^9.33.0",
41
+ "jsdom": "^25.0.1",
42
+ "typescript": "^5.9.2",
43
+ "vite": "^7.1.5",
44
+ "vite-plugin-dts": "^4.5.4",
45
+ "vitest": "^2.1.8",
46
+ "@flemo/eslint-config": "0.0.0",
47
+ "@flemo/tsconfig": "0.0.0"
48
+ },
49
+ "publishConfig": {
50
+ "access": "public"
51
+ },
52
+ "scripts": {
53
+ "build": "vite build",
54
+ "watch": "vite build --watch",
55
+ "dev": "vite build --watch",
56
+ "lint": "eslint \"**/*.{js,mjs,ts,jsx,tsx,mts}\"",
57
+ "typecheck": "tsc --noEmit",
58
+ "test": "vitest run",
59
+ "test:watch": "vitest",
60
+ "clean": "rm -rf dist .turbo"
61
+ }
62
+ }