@golemui/core 0.0.2 → 0.12.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 +15 -6
- package/index.d.ts +10 -6
- package/index.js +1336 -1018
- package/index.umd.cjs +8 -8
- package/lib/context/form.context.d.ts +9 -4
- package/lib/context/widget-registry.d.ts +6 -1
- package/lib/errors.d.ts +10 -0
- package/lib/form-validator.d.ts +2 -7
- package/lib/form-widget.d.ts +1 -0
- package/lib/form.d.ts +19 -2
- package/lib/i18n.d.ts +19 -3
- package/lib/middleware/devtools/devtools.middleware.d.ts +17 -0
- package/lib/middleware/index.d.ts +1 -2
- package/lib/shared.d.ts +21 -0
- package/lib/store/actions.d.ts +18 -2
- package/lib/store/model.d.ts +19 -10
- package/lib/store/reducers/index.d.ts +2 -1
- package/lib/store/reducers/set-meta.d.ts +3 -0
- package/lib/store/reducers/utils.d.ts +0 -2
- package/lib/store/reducers/validate-all.d.ts +2 -1
- package/lib/store/selectors.d.ts +5 -1
- package/lib/utils/array.d.ts +60 -0
- package/lib/utils/assert-no-prop-collisions.d.ts +9 -0
- package/lib/utils/dev-mode.d.ts +2 -0
- package/lib/utils/form.d.ts +59 -0
- package/lib/utils/justin.d.ts +3 -0
- package/lib/utils/object.d.ts +4 -2
- package/lib/utils/repeater.d.ts +31 -1
- package/package.json +6 -1
- package/CHANGELOG.md +0 -517
- package/lib/middleware/json-schema/json-schema.d.ts +0 -67
- package/lib/middleware/json-schema/json-schema.middleware.d.ts +0 -19
- package/lib/utils/dot-path.d.ts +0 -16
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { DotPath } from '../../shared';
|
|
2
1
|
import { State } from '../model';
|
|
3
2
|
/**
|
|
4
3
|
* Conditionally applies a reducer function based on a predicate
|
|
@@ -26,7 +25,6 @@ import { State } from '../model';
|
|
|
26
25
|
* ```
|
|
27
26
|
*/
|
|
28
27
|
export declare const reduceIf: (predicate: (state: State) => boolean, reducerFn: (state: State) => State) => (state: State) => State;
|
|
29
|
-
export declare const isControlTouched: (widgetPath: DotPath) => (state: State) => boolean;
|
|
30
28
|
export declare const hasWhen: (val: unknown) => val is {
|
|
31
29
|
when: string;
|
|
32
30
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { ValidatorFn } from '../../form-validator';
|
|
2
|
+
import { I18nTranslator } from '../../i18n';
|
|
2
3
|
import { State } from '../model';
|
|
3
|
-
export declare const validateAll: (validators: ValidatorFn<any
|
|
4
|
+
export declare const validateAll: (validators: ValidatorFn<any>, localization: I18nTranslator) => (state: State) => State;
|
package/lib/store/selectors.d.ts
CHANGED
|
@@ -5,7 +5,11 @@ import { State } from './model';
|
|
|
5
5
|
export declare const dataByPath$: <T = any>(path: DotPath) => import('rxjs').UnaryFunction<Observable<State>, Observable<T>>;
|
|
6
6
|
export declare const validationByPath$: (path: DotPath) => import('rxjs').UnaryFunction<Observable<State>, Observable<import('../shared').ValidationStatus>>;
|
|
7
7
|
export declare const injectedValidationByPath$: (path: DotPath) => import('rxjs').UnaryFunction<Observable<State>, Observable<import('../shared').ValidationStatus>>;
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Emits the current calculated widget for the given uid
|
|
10
|
+
* Re triggers on widget changes OR store.lang changes
|
|
11
|
+
*/
|
|
12
|
+
export declare const calculatedWidgetsByUid$: (uid: Uid) => (state$: Observable<State>) => Observable<import('../form-widget').NonFunctionWidget<string, any, any>>;
|
|
9
13
|
export declare const calculatedLayoutChildrenByUid$: (uid: Uid) => import('rxjs').UnaryFunction<Observable<State>, Observable<(import('../form-widget').DisplayWidget<never, any, any> | import('../form-widget').InputWidget<any, never, any, any, any> | LayoutWidget<never, any, any, (import('../form-widget').DisplayWidget<never, any, any> | import('../form-widget').InputWidget<any, never, any, any, any> | LayoutWidget<never, any, any, (import('../form-widget').DisplayWidget<never, any, any> | import('../form-widget').InputWidget<any, never, any, any, any> | LayoutWidget<never, any, any, (import('../form-widget').DisplayWidget<never, any, any> | import('../form-widget').InputWidget<any, never, any, any, any> | LayoutWidget<never, any, any, (import('../form-widget').DisplayWidget<never, any, any> | import('../form-widget').InputWidget<any, never, any, any, any> | LayoutWidget<never, any, any, (import('../form-widget').DisplayWidget<never, any, any> | import('../form-widget').InputWidget<any, never, any, any, any> | LayoutWidget<never, any, any, (import('../form-widget').DisplayWidget<never, any, any> | import('../form-widget').InputWidget<any, never, any, any, any> | LayoutWidget<never, any, any, (import('../form-widget').DisplayWidget<never, any, any> | import('../form-widget').InputWidget<any, never, any, any, any> | LayoutWidget<never, any, any, (import('../form-widget').DisplayWidget<never, any, any> | import('../form-widget').InputWidget<any, never, any, any, any> | LayoutWidget<never, any, any, (import('../form-widget').DisplayWidget<never, any, any> | import('../form-widget').InputWidget<any, never, any, any, any> | LayoutWidget<never, any, any, (import('../form-widget').DisplayWidget<never, any, any> | import('../form-widget').InputWidget<any, never, any, any, any> | LayoutWidget<never, any, any, /*elided*/ any> | import('../form-widget').ActionWidget<never, any, any> | import('../form-widget').FunctionWidget<never, any, any>)[]> | import('../form-widget').ActionWidget<never, any, any> | import('../form-widget').FunctionWidget<never, any, any>)[]> | import('../form-widget').ActionWidget<never, any, any> | import('../form-widget').FunctionWidget<never, any, any>)[]> | import('../form-widget').ActionWidget<never, any, any> | import('../form-widget').FunctionWidget<never, any, any>)[]> | import('../form-widget').ActionWidget<never, any, any> | import('../form-widget').FunctionWidget<never, any, any>)[]> | import('../form-widget').ActionWidget<never, any, any> | import('../form-widget').FunctionWidget<never, any, any>)[]> | import('../form-widget').ActionWidget<never, any, any> | import('../form-widget').FunctionWidget<never, any, any>)[]> | import('../form-widget').ActionWidget<never, any, any> | import('../form-widget').FunctionWidget<never, any, any>)[]> | import('../form-widget').ActionWidget<never, any, any> | import('../form-widget').FunctionWidget<never, any, any>)[]> | import('../form-widget').ActionWidget<never, any, any> | import('../form-widget').FunctionWidget<never, any, any>)[]> | import('../form-widget').ActionWidget<never, any, any> | import('../form-widget').FunctionWidget<never, any, any>)[]>>;
|
|
10
14
|
export declare const selectWidgetFlags: import('rxjs').UnaryFunction<Observable<State>, Observable<Record<string, {
|
|
11
15
|
hidden?: boolean;
|
package/lib/utils/array.d.ts
CHANGED
|
@@ -30,6 +30,66 @@ export declare const SKIP: unique symbol;
|
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
32
|
export declare function filterMap<T, U>(array: readonly T[], fn: (value: T, index: number, array: readonly T[]) => U | typeof SKIP): U[];
|
|
33
|
+
/**
|
|
34
|
+
* Iterates over an array, executing a callback function only for elements
|
|
35
|
+
* that satisfy the provided predicate.
|
|
36
|
+
*
|
|
37
|
+
* This combines `filter` and `forEach` in a single pass without allocating
|
|
38
|
+
* intermediate arrays, improving performance and reducing garbage collection.
|
|
39
|
+
*
|
|
40
|
+
* @typeParam T - The type of the input array elements.
|
|
41
|
+
* @typeParam S - A narrower type of the elements that pass a type guard predicate.
|
|
42
|
+
*
|
|
43
|
+
* @param array - The source array to iterate over.
|
|
44
|
+
* @param predicate - A function that evaluates each element. If it returns truthy,
|
|
45
|
+
* the callback is executed.
|
|
46
|
+
* @param callback - A function to execute for each element that passes the predicate.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* filterTap(
|
|
51
|
+
* [1, 2, 3, 4],
|
|
52
|
+
* n => n % 2 === 0,
|
|
53
|
+
* n => console.log('Even:', n)
|
|
54
|
+
* );
|
|
55
|
+
* // "Even: 2", "Even: 4"
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare function filterTap<T, S extends T>(array: readonly T[], predicate: (value: T, index: number, array: readonly T[]) => value is S, callback: (value: S, index: number, array: readonly T[]) => void): void;
|
|
59
|
+
export declare function filterTap<T>(array: readonly T[], predicate: (value: T, index: number, array: readonly T[]) => unknown, callback: (value: T, index: number, array: readonly T[]) => void): void;
|
|
60
|
+
/**
|
|
61
|
+
* Iterates over an array, filtering elements using a predicate, and
|
|
62
|
+
* accumulating a single result using a reducer function.
|
|
63
|
+
*
|
|
64
|
+
* This combines `filter` and `reduce` in a single pass without allocating
|
|
65
|
+
* intermediate arrays, improving performance and memory efficiency.
|
|
66
|
+
*
|
|
67
|
+
* @typeParam T - The type of the input array elements.
|
|
68
|
+
* @typeParam S - A narrower type of the elements that pass a type guard predicate.
|
|
69
|
+
* @typeParam U - The type of the accumulated value.
|
|
70
|
+
*
|
|
71
|
+
* @param array - The source array to iterate over.
|
|
72
|
+
* @param predicate - A function that evaluates each element. If truthy, the element
|
|
73
|
+
* is passed to the reducer.
|
|
74
|
+
* @param reducer - A function that accumulates the results.
|
|
75
|
+
* @param initialValue - The initial value to start the accumulation. Required to ensure
|
|
76
|
+
* safety in cases where no elements pass the predicate.
|
|
77
|
+
*
|
|
78
|
+
* @returns The final accumulated value.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* const sumOfEvens = filterReduce(
|
|
83
|
+
* [1, 2, 3, 4, 5],
|
|
84
|
+
* n => n % 2 === 0,
|
|
85
|
+
* (acc, n) => acc + n,
|
|
86
|
+
* 0
|
|
87
|
+
* );
|
|
88
|
+
* // sumOfEvens: 6
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export declare function filterReduce<T, S extends T, U>(array: readonly T[], predicate: (value: T, index: number, array: readonly T[]) => value is S, reducer: (accumulator: U, currentValue: S, index: number, array: readonly T[]) => U, initialValue: U): U;
|
|
92
|
+
export declare function filterReduce<T, U>(array: readonly T[], predicate: (value: T, index: number, array: readonly T[]) => unknown, reducer: (accumulator: U, currentValue: T, index: number, array: readonly T[]) => U, initialValue: U): U;
|
|
33
93
|
/**
|
|
34
94
|
* Compares two arrays for structural equality by applying a predicate
|
|
35
95
|
* to each pair of elements.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Throws when properties in widget.props collide with base widget props, which should never happen.
|
|
3
|
+
* Only runs when dev mode is enabled via enableDevMode().
|
|
4
|
+
*
|
|
5
|
+
* @param widgetUid to describe which field has collisions
|
|
6
|
+
* @param props widget.props
|
|
7
|
+
* @param base widget props
|
|
8
|
+
*/
|
|
9
|
+
export declare function assertNoPropCollisions(widgetUid: string, props: Record<string, unknown> | undefined, base: Record<string, unknown>): void;
|
package/lib/utils/form.d.ts
CHANGED
|
@@ -1,4 +1,55 @@
|
|
|
1
|
+
import { $Errors, DotPath } from '../shared';
|
|
2
|
+
import { State } from '../store/model';
|
|
1
3
|
import * as Widget from '../form-widget';
|
|
4
|
+
/**
|
|
5
|
+
* Expression Scopes define the root namespaces accessible within
|
|
6
|
+
* reactive expressions and template strings.
|
|
7
|
+
*/
|
|
8
|
+
export declare const EXPRESSION_SCOPE: {
|
|
9
|
+
readonly FORM: "$form";
|
|
10
|
+
readonly META: "$meta";
|
|
11
|
+
readonly ERRORS: "$errors";
|
|
12
|
+
readonly FORM_IS_INVALID: "$formIsInvalid";
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Heuristically checks if a value looks like a scoped path
|
|
16
|
+
* rather than a standard string.
|
|
17
|
+
* To be considered a "potential" scoped path, the value must:
|
|
18
|
+
* 1. Be a string.
|
|
19
|
+
* 2. Start with one of the allowed prefixes ($form.*, $meta.*, etc..).
|
|
20
|
+
* 3. Not contain any spaces (distinguishing it from sentences).
|
|
21
|
+
*
|
|
22
|
+
* * @example
|
|
23
|
+
* isPotentialScopedPath('$form.user.id'); // true
|
|
24
|
+
* isPotentialScopedPath('name'); // false (No prefix)
|
|
25
|
+
* isPotentialScopedPath('my file'); // false (Contains space)
|
|
26
|
+
* isPotentialScopedPath(123); // false (Not a string)
|
|
27
|
+
*/
|
|
28
|
+
export declare const isPotentialScopedPath: (path: unknown) => path is DotPath;
|
|
29
|
+
export interface ScopedPathResolvers {
|
|
30
|
+
resolveFormPath: (expr: string) => any;
|
|
31
|
+
resolveMetaPath: (expr: string) => any;
|
|
32
|
+
resolveErrorsPath: (expr: string) => any;
|
|
33
|
+
resolveFormIsInvalid: () => string | boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Resolves all scoped path placeholders within a string in a single pass.
|
|
37
|
+
* e.g. "User {{ $form.name }} has status {{ $meta.status }} or {{ $formIsInvalid }}"
|
|
38
|
+
*
|
|
39
|
+
* @param input - The template string to process
|
|
40
|
+
* @param resolvers - Implementation of value resolution logic
|
|
41
|
+
* @returns The string with all valid placeholders replaced by their resolved values
|
|
42
|
+
*/
|
|
43
|
+
export declare const resolveScopedPaths: (input: string, resolvers: ScopedPathResolvers) => string;
|
|
44
|
+
/**
|
|
45
|
+
* Resolves a scoped path to its underlying value using the
|
|
46
|
+
* appropriate resolver based on the path prefix (`$form.*`, `$meta.*`, `$errors.*` or `$formIsInvalid`).
|
|
47
|
+
*
|
|
48
|
+
* @param variable - A dot-notation path starting with `$form.`, `$meta.` or `$errors.`, or `$formIsInvalid`.
|
|
49
|
+
* @param resolvers.resolveFormPath - Resolves a path within the $form scope
|
|
50
|
+
* @param resolvers.resolveMetaPath - Resolves a path within the $meta scope
|
|
51
|
+
*/
|
|
52
|
+
export declare const resolveScopedPath: (variable: string, resolvers: ScopedPathResolvers) => any;
|
|
2
53
|
/**
|
|
3
54
|
* Flattens the hierarchical form structure into a single-level array of form widgets.
|
|
4
55
|
*
|
|
@@ -18,3 +69,11 @@ import * as Widget from '../form-widget';
|
|
|
18
69
|
* ```
|
|
19
70
|
*/
|
|
20
71
|
export declare function flattenForm(widgets: Widget.FormWidget[]): Widget.FormWidget[];
|
|
72
|
+
/**
|
|
73
|
+
* Calculates validation variables to be used in reactive expressions
|
|
74
|
+
* e.g. `{ invalidAge: '!!$errors.age' }` or { disabled { when: '$formIsInvalid' } }
|
|
75
|
+
*/
|
|
76
|
+
export declare function calculateValidationVariables(state: State): {
|
|
77
|
+
$formIsInvalid: boolean;
|
|
78
|
+
$errors: $Errors;
|
|
79
|
+
};
|
package/lib/utils/object.d.ts
CHANGED
|
@@ -135,6 +135,8 @@ export declare const set: (object: Record<string, any>, path: DotPath, value: an
|
|
|
135
135
|
*/
|
|
136
136
|
export declare const deleteKey: (object: Record<string, any>, key: string) => Record<string, any>;
|
|
137
137
|
/**
|
|
138
|
-
*
|
|
138
|
+
* Deep-clones plain objects and arrays while preserving function references
|
|
139
|
+
* (and other non-plain values) by reference. Functions are stateless widget
|
|
140
|
+
* resolvers and only need to survive the trip into repeater item configs.
|
|
139
141
|
*/
|
|
140
|
-
export declare function cloneObject(
|
|
142
|
+
export declare function cloneObject<T>(value: T): T;
|
package/lib/utils/repeater.d.ts
CHANGED
|
@@ -1,2 +1,32 @@
|
|
|
1
1
|
import { NonFunctionWidget } from '../form-widget';
|
|
2
|
-
|
|
2
|
+
import { Uid } from '../shared';
|
|
3
|
+
/**
|
|
4
|
+
* Derives a concrete widget config for a specific repeater item by stamping
|
|
5
|
+
* the provided indexes into the widget's `uid` (and `path` for input widgets).
|
|
6
|
+
*
|
|
7
|
+
* @param widget - The base widget config defined on the repeater template.
|
|
8
|
+
* @param repeaterIndexes - Ordered list of indexes for each nesting level,
|
|
9
|
+
* e.g. `[2, 0]` for the first item of a nested repeater inside the third
|
|
10
|
+
* item of an outer repeater.
|
|
11
|
+
* @returns A new widget config with the indexes baked in; the original is not mutated.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* makeRepeaterItemConfig(widget, [1]) // { uid: 'user-name[1]', path: 'users.1.name' }
|
|
15
|
+
*/
|
|
16
|
+
export declare function makeRepeaterItemConfig(widget: NonFunctionWidget<string>, repeaterIndexes: number[]): NonFunctionWidget<string>;
|
|
17
|
+
export declare function toRepeaterItemUid(uid: Uid, repeaterIndexes: number[]): Uid;
|
|
18
|
+
/**
|
|
19
|
+
* Replaces `.items.` and `.items?.` tokens in a `when` expression with the
|
|
20
|
+
* concrete repeater indexes so the expression can be evaluated.
|
|
21
|
+
* Multiple `items` tokens are replaced in order, supporting nested repeaters.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // repeaterIndexes = [2]
|
|
25
|
+
* // "$form.reptr.items.active" -> "$form.reptr.2.active"
|
|
26
|
+
* // "$form.reptr.items?.active" -> "$form.reptr.2?.active"
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* // repeaterIndexes = [1, 0]
|
|
30
|
+
* // "$form.reptr.teams.items?.devs?.items?.firstName?.length > 0" -> "$form.reptr.teams.1?.devs?.0?.firstName?.length > 0"
|
|
31
|
+
*/
|
|
32
|
+
export declare function transformRepeaterItemWhenExpression(expression: string, repeaterIndexes: number[]): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@golemui/core",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./index.umd.cjs",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -26,5 +26,10 @@
|
|
|
26
26
|
"subscript": "^10.1.8",
|
|
27
27
|
"rxjs": "^7.8.0",
|
|
28
28
|
"@standard-schema/spec": "^1.0.0"
|
|
29
|
+
},
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/golemui/golemui.git",
|
|
33
|
+
"directory": "libs/core"
|
|
29
34
|
}
|
|
30
35
|
}
|