@jfdevelops/react-layout 2.3.0 → 2.5.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/dist/create-config/create-defined-resource-layout.cjs.map +1 -1
- package/dist/create-config/create-defined-resource-layout.d.cts +1 -1
- package/dist/create-config/create-defined-resource-layout.d.cts.map +1 -1
- package/dist/create-config/create-defined-resource-layout.d.mts +1 -1
- package/dist/create-config/create-defined-resource-layout.d.mts.map +1 -1
- package/dist/create-config/create-defined-resource-layout.mjs.map +1 -1
- package/dist/create-config/create-reusable.cjs +198 -21
- package/dist/create-config/create-reusable.cjs.map +1 -1
- package/dist/create-config/create-reusable.d.cts +2 -41
- package/dist/create-config/create-reusable.d.mts +2 -41
- package/dist/create-config/create-reusable.mjs +198 -21
- package/dist/create-config/create-reusable.mjs.map +1 -1
- package/dist/create-config/index.d.cts +2 -1
- package/dist/create-config/index.d.mts +2 -1
- package/dist/create-config/merge-layout-props.cjs.map +1 -1
- package/dist/create-config/merge-layout-props.mjs.map +1 -1
- package/dist/create-config/reusable-resource-input.cjs +22 -0
- package/dist/create-config/reusable-resource-input.cjs.map +1 -0
- package/dist/create-config/reusable-resource-input.d.cts +16 -0
- package/dist/create-config/reusable-resource-input.d.cts.map +1 -0
- package/dist/create-config/reusable-resource-input.d.mts +16 -0
- package/dist/create-config/reusable-resource-input.d.mts.map +1 -0
- package/dist/create-config/reusable-resource-input.mjs +19 -0
- package/dist/create-config/reusable-resource-input.mjs.map +1 -0
- package/dist/create-config/reusable-types.d.cts +139 -0
- package/dist/create-config/reusable-types.d.cts.map +1 -0
- package/dist/create-config/reusable-types.d.mts +139 -0
- package/dist/create-config/reusable-types.d.mts.map +1 -0
- package/dist/index.d.cts +4 -3
- package/dist/index.d.mts +4 -3
- package/dist/props.cjs.map +1 -1
- package/dist/props.d.cts +6 -1
- package/dist/props.d.cts.map +1 -1
- package/dist/props.d.mts +6 -1
- package/dist/props.d.mts.map +1 -1
- package/dist/props.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/create-config/create-reusable.d.cts.map +0 -1
- package/dist/create-config/create-reusable.d.mts.map +0 -1
|
@@ -1,41 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { AnyBuiltPropDefinition, ExtractDefinitionValue, ResolvedBuiltPropShape } from "@jfdevelops/react-layout-validator";
|
|
4
|
-
|
|
5
|
-
//#region src/create-config/create-reusable.d.ts
|
|
6
|
-
/** Object definitions can be selected recursively; other definitions are leaves. */
|
|
7
|
-
type ReusableOptionSelection<Props extends InPropsObject> = { [Key in keyof Props]?: Props[Key] extends {
|
|
8
|
-
type: 'object';
|
|
9
|
-
properties: infer Shape extends InPropsObject;
|
|
10
|
-
} ? true | ReusableOptionSelection<Shape> : true };
|
|
11
|
-
type OptionDefinitions<Resources extends readonly ResourceDefinition[], Options extends InPropsDefinition<Resources>> = InferredInProps<Resources, Options> extends infer Props extends InPropsObject ? Props : never;
|
|
12
|
-
/** Only data sources declared by the factory are available for selection. */
|
|
13
|
-
type ReusableInclude<Resources extends readonly ResourceDefinition[], Options extends InPropsDefinition<Resources>> = {
|
|
14
|
-
resources?: true;
|
|
15
|
-
} & (keyof OptionDefinitions<Resources, Options> extends never ? {} : {
|
|
16
|
-
options?: true | ReusableOptionSelection<OptionDefinitions<Resources, Options>>;
|
|
17
|
-
});
|
|
18
|
-
type SelectedOptionValue<Definition extends AnyBuiltPropDefinition, Selection> = Selection extends true ? ExtractDefinitionValue<Definition> : Definition extends {
|
|
19
|
-
properties: infer Shape extends InPropsObject;
|
|
20
|
-
} ? SelectedOptionProps<Shape, Selection> : never;
|
|
21
|
-
type SelectedOptionProps<Props extends InPropsObject, Selection> = { [Key in keyof Props & keyof Selection as Props[Key]['visibility'] extends 'required' ? Key : never]: SelectedOptionValue<Props[Key], Selection[Key]> } & { [Key in keyof Props & keyof Selection as Props[Key]['visibility'] extends 'optional' ? Key : never]?: SelectedOptionValue<Props[Key], Selection[Key]> };
|
|
22
|
-
/** Options are flattened one level, so `options: { meta: true }` supplies `meta`. */
|
|
23
|
-
type ReusableProps<Resources extends readonly ResourceDefinition[], Options extends InPropsDefinition<Resources>, Include, Custom extends InPropsObject> = (Include extends {
|
|
24
|
-
resources: true;
|
|
25
|
-
} ? {
|
|
26
|
-
resources: ResourceEnum<Resources>[number][];
|
|
27
|
-
} : {}) & (Include extends {
|
|
28
|
-
options: infer Selection;
|
|
29
|
-
} ? Selection extends true ? ResolvedBuiltPropShape<OptionDefinitions<Resources, Options>> : SelectedOptionProps<OptionDefinitions<Resources, Options>, Selection> : {}) & ResolvedBuiltPropShape<Custom>;
|
|
30
|
-
type ExactSelection<Selection, Allowed> = { [Key in keyof Selection]: Key extends keyof Allowed ? Selection[Key] extends object ? ExactSelection<Selection[Key], Exclude<Allowed[Key], true | undefined>> : Allowed[Key] : never };
|
|
31
|
-
/** Creates a validated ordinary function with the shared configuration's types. */
|
|
32
|
-
type CreateReusable<Resources extends readonly ResourceDefinition[], Options extends InPropsDefinition<Resources>> = <const Include extends ReusableInclude<Resources, Options> = {}, const Custom extends InPropsObject = {}, Result = unknown>(definition: {
|
|
33
|
-
props?: {
|
|
34
|
-
include?: ReusableInclude<Resources, Options> & Include & ExactSelection<Include, ReusableInclude<Resources, Options>>;
|
|
35
|
-
custom?: Custom;
|
|
36
|
-
};
|
|
37
|
-
fn: (props: ReusableProps<Resources, Options, Include, Custom>) => Result;
|
|
38
|
-
}) => (...args: {} extends ReusableProps<Resources, Options, Include, Custom> ? [props?: ReusableProps<Resources, Options, Include, Custom>] : [props: ReusableProps<Resources, Options, Include, Custom>]) => Result;
|
|
39
|
-
//#endregion
|
|
40
|
-
export { CreateReusable, ReusableInclude, ReusableOptionSelection, ReusableProps };
|
|
41
|
-
//# sourceMappingURL=create-reusable.d.cts.map
|
|
1
|
+
import { ReusableResourcesAccessor, SingleResourceInput } from "./reusable-resource-input.cjs";
|
|
2
|
+
import { CreateReusable, ReusableArguments, ReusableDefinition, ReusableFunction, ReusableInclude, ReusableInput, ReusableOptionSelection, ReusableOverlap, ReusableProps, ReusableResolved, ReusableSelected } from "./reusable-types.cjs";
|
|
@@ -1,41 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { AnyBuiltPropDefinition, ExtractDefinitionValue, ResolvedBuiltPropShape } from "@jfdevelops/react-layout-validator";
|
|
4
|
-
|
|
5
|
-
//#region src/create-config/create-reusable.d.ts
|
|
6
|
-
/** Object definitions can be selected recursively; other definitions are leaves. */
|
|
7
|
-
type ReusableOptionSelection<Props extends InPropsObject> = { [Key in keyof Props]?: Props[Key] extends {
|
|
8
|
-
type: 'object';
|
|
9
|
-
properties: infer Shape extends InPropsObject;
|
|
10
|
-
} ? true | ReusableOptionSelection<Shape> : true };
|
|
11
|
-
type OptionDefinitions<Resources extends readonly ResourceDefinition[], Options extends InPropsDefinition<Resources>> = InferredInProps<Resources, Options> extends infer Props extends InPropsObject ? Props : never;
|
|
12
|
-
/** Only data sources declared by the factory are available for selection. */
|
|
13
|
-
type ReusableInclude<Resources extends readonly ResourceDefinition[], Options extends InPropsDefinition<Resources>> = {
|
|
14
|
-
resources?: true;
|
|
15
|
-
} & (keyof OptionDefinitions<Resources, Options> extends never ? {} : {
|
|
16
|
-
options?: true | ReusableOptionSelection<OptionDefinitions<Resources, Options>>;
|
|
17
|
-
});
|
|
18
|
-
type SelectedOptionValue<Definition extends AnyBuiltPropDefinition, Selection> = Selection extends true ? ExtractDefinitionValue<Definition> : Definition extends {
|
|
19
|
-
properties: infer Shape extends InPropsObject;
|
|
20
|
-
} ? SelectedOptionProps<Shape, Selection> : never;
|
|
21
|
-
type SelectedOptionProps<Props extends InPropsObject, Selection> = { [Key in keyof Props & keyof Selection as Props[Key]['visibility'] extends 'required' ? Key : never]: SelectedOptionValue<Props[Key], Selection[Key]> } & { [Key in keyof Props & keyof Selection as Props[Key]['visibility'] extends 'optional' ? Key : never]?: SelectedOptionValue<Props[Key], Selection[Key]> };
|
|
22
|
-
/** Options are flattened one level, so `options: { meta: true }` supplies `meta`. */
|
|
23
|
-
type ReusableProps<Resources extends readonly ResourceDefinition[], Options extends InPropsDefinition<Resources>, Include, Custom extends InPropsObject> = (Include extends {
|
|
24
|
-
resources: true;
|
|
25
|
-
} ? {
|
|
26
|
-
resources: ResourceEnum<Resources>[number][];
|
|
27
|
-
} : {}) & (Include extends {
|
|
28
|
-
options: infer Selection;
|
|
29
|
-
} ? Selection extends true ? ResolvedBuiltPropShape<OptionDefinitions<Resources, Options>> : SelectedOptionProps<OptionDefinitions<Resources, Options>, Selection> : {}) & ResolvedBuiltPropShape<Custom>;
|
|
30
|
-
type ExactSelection<Selection, Allowed> = { [Key in keyof Selection]: Key extends keyof Allowed ? Selection[Key] extends object ? ExactSelection<Selection[Key], Exclude<Allowed[Key], true | undefined>> : Allowed[Key] : never };
|
|
31
|
-
/** Creates a validated ordinary function with the shared configuration's types. */
|
|
32
|
-
type CreateReusable<Resources extends readonly ResourceDefinition[], Options extends InPropsDefinition<Resources>> = <const Include extends ReusableInclude<Resources, Options> = {}, const Custom extends InPropsObject = {}, Result = unknown>(definition: {
|
|
33
|
-
props?: {
|
|
34
|
-
include?: ReusableInclude<Resources, Options> & Include & ExactSelection<Include, ReusableInclude<Resources, Options>>;
|
|
35
|
-
custom?: Custom;
|
|
36
|
-
};
|
|
37
|
-
fn: (props: ReusableProps<Resources, Options, Include, Custom>) => Result;
|
|
38
|
-
}) => (...args: {} extends ReusableProps<Resources, Options, Include, Custom> ? [props?: ReusableProps<Resources, Options, Include, Custom>] : [props: ReusableProps<Resources, Options, Include, Custom>]) => Result;
|
|
39
|
-
//#endregion
|
|
40
|
-
export { CreateReusable, ReusableInclude, ReusableOptionSelection, ReusableProps };
|
|
41
|
-
//# sourceMappingURL=create-reusable.d.mts.map
|
|
1
|
+
import { ReusableResourcesAccessor, SingleResourceInput } from "./reusable-resource-input.mjs";
|
|
2
|
+
import { CreateReusable, ReusableArguments, ReusableDefinition, ReusableFunction, ReusableInclude, ReusableInput, ReusableOptionSelection, ReusableOverlap, ReusableProps, ReusableResolved, ReusableSelected } from "./reusable-types.mjs";
|
|
@@ -1,44 +1,221 @@
|
|
|
1
1
|
import { LayoutConfigurationError } from "../errors/layout-configuration-error.mjs";
|
|
2
|
+
import { createLayoutResourcesAccessor } from "./define-layout.mjs";
|
|
3
|
+
import { getResourcePaths, isSingleResourceInput, singleResourceInput } from "./reusable-resource-input.mjs";
|
|
2
4
|
import { createProp, validateProps } from "@jfdevelops/react-layout-validator";
|
|
3
5
|
|
|
4
6
|
//#region src/create-config/create-reusable.ts
|
|
5
|
-
function
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
function objectPlan(children, optional = false, guards = [[]]) {
|
|
8
|
+
return {
|
|
9
|
+
kind: "object",
|
|
10
|
+
children,
|
|
11
|
+
optional,
|
|
12
|
+
guards
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function optionPlan(definitions, selection, from, path = [], optionalPaths = []) {
|
|
16
|
+
const entries = selection === true ? Object.fromEntries(Object.keys(definitions).map((key) => [key, true])) : selection;
|
|
17
|
+
const children = {};
|
|
18
|
+
for (const [key, value] of Object.entries(entries ?? {})) {
|
|
9
19
|
if (!Object.hasOwn(definitions, key)) throw new LayoutConfigurationError(`Unknown reusable option "${key}".`);
|
|
10
|
-
|
|
11
|
-
|
|
20
|
+
const definition = definitions[key];
|
|
21
|
+
const location = {
|
|
22
|
+
from,
|
|
23
|
+
path: [...path, key]
|
|
24
|
+
};
|
|
25
|
+
if (typeof value === "function") children[key] = {
|
|
26
|
+
...location,
|
|
27
|
+
from: "options",
|
|
28
|
+
guards: optionalPaths.map((path) => ({
|
|
29
|
+
from: "options",
|
|
30
|
+
path
|
|
31
|
+
})),
|
|
32
|
+
kind: "value",
|
|
33
|
+
source: "option",
|
|
34
|
+
selector: value,
|
|
35
|
+
definition
|
|
36
|
+
};
|
|
37
|
+
else if ("properties" in definition && "type" in definition && definition.type === "object" && (value === true || value && typeof value === "object")) children[key] = {
|
|
38
|
+
...optionPlan(definition.properties, value, from, location.path, definition.visibility === "optional" ? [...optionalPaths, location.path] : optionalPaths),
|
|
39
|
+
optional: definition.visibility === "optional"
|
|
40
|
+
};
|
|
41
|
+
else if (value === true) children[key] = {
|
|
42
|
+
...location,
|
|
43
|
+
guards: optionalPaths.map((path) => ({
|
|
44
|
+
from,
|
|
45
|
+
path
|
|
46
|
+
})),
|
|
47
|
+
kind: "value",
|
|
48
|
+
source: "option",
|
|
49
|
+
definition
|
|
50
|
+
};
|
|
51
|
+
else throw new LayoutConfigurationError(`Invalid reusable selection for "${key}".`);
|
|
52
|
+
}
|
|
53
|
+
const origins = /* @__PURE__ */ new Set();
|
|
54
|
+
function collectOrigins(node) {
|
|
55
|
+
if (node.kind === "value") origins.add(node.from);
|
|
56
|
+
else Object.values(node.children).forEach(collectOrigins);
|
|
57
|
+
}
|
|
58
|
+
Object.values(children).forEach(collectOrigins);
|
|
59
|
+
if (!origins.size) origins.add(from);
|
|
60
|
+
return objectPlan(children, false, [...origins].map((origin) => optionalPaths.map((path) => ({
|
|
61
|
+
from: origin,
|
|
62
|
+
path
|
|
63
|
+
}))));
|
|
64
|
+
}
|
|
65
|
+
function sameSelection(left, right) {
|
|
66
|
+
return left.source === right.source && left.selector === right.selector && left.path.join(".") === right.path.join(".") && (left.source === "option" || left.from === right.from);
|
|
67
|
+
}
|
|
68
|
+
function mergePlans(left, right, overlap, path = []) {
|
|
69
|
+
const children = { ...left.children };
|
|
70
|
+
for (const [key, other] of Object.entries(right.children)) {
|
|
71
|
+
const current = children[key];
|
|
72
|
+
if (!current) {
|
|
73
|
+
children[key] = other;
|
|
12
74
|
continue;
|
|
13
75
|
}
|
|
14
|
-
if (
|
|
15
|
-
|
|
16
|
-
|
|
76
|
+
if (current.kind === "object" && other.kind === "object") children[key] = mergePlans(current, other, overlap, [...path, key]);
|
|
77
|
+
else if (current.kind === "value" && other.kind === "value" && sameSelection(current, other)) children[key] = other.from === "options" ? other : current;
|
|
78
|
+
else if (overlap) children[key] = overlap === "preferProps" ? current : other;
|
|
79
|
+
else throw new LayoutConfigurationError(`Ambiguous reusable property "${[...path, key].join(".")}". Rename one result or set overlap to "preferProps" or "preferSelect".`);
|
|
17
80
|
}
|
|
18
|
-
return
|
|
81
|
+
return {
|
|
82
|
+
kind: "object",
|
|
83
|
+
children,
|
|
84
|
+
optional: left.optional && right.optional,
|
|
85
|
+
guards: [...left.guards, ...right.guards]
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function withoutSharedCallerValues(left, right) {
|
|
89
|
+
const children = { ...left.children };
|
|
90
|
+
for (const [key, other] of Object.entries(right.children)) {
|
|
91
|
+
const current = children[key];
|
|
92
|
+
if (current?.kind === "object" && other.kind === "object") children[key] = withoutSharedCallerValues(current, other);
|
|
93
|
+
else if (current?.kind === "value" && other.kind === "value" && sameSelection(current, other) && other.from === "options") delete children[key];
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
...left,
|
|
97
|
+
children
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function planDefinitions(plan, from) {
|
|
101
|
+
const definitions = {};
|
|
102
|
+
for (const [key, value] of Object.entries(plan.children)) if (value.kind === "value") {
|
|
103
|
+
if (value.from === from && value.definition) definitions[key] = value.definition;
|
|
104
|
+
} else {
|
|
105
|
+
const nested = planDefinitions(value, from);
|
|
106
|
+
if (Object.keys(nested).length) {
|
|
107
|
+
const definition = createProp.object(nested);
|
|
108
|
+
definitions[key] = value.optional ? definition.optional() : definition;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return definitions;
|
|
112
|
+
}
|
|
113
|
+
function sourceSelection(selection, callbacksOnly) {
|
|
114
|
+
if (typeof selection === "function") return true;
|
|
115
|
+
if (selection === true) return callbacksOnly ? {} : true;
|
|
116
|
+
const source = {};
|
|
117
|
+
for (const [key, value] of Object.entries(selection ?? {})) {
|
|
118
|
+
const nested = sourceSelection(value, callbacksOnly);
|
|
119
|
+
if (nested === true || Object.keys(nested).length) source[key] = nested;
|
|
120
|
+
}
|
|
121
|
+
return source;
|
|
122
|
+
}
|
|
123
|
+
function mergeSelections(left, right) {
|
|
124
|
+
if (left === true || right === true) return true;
|
|
125
|
+
const merged = { ...left };
|
|
126
|
+
for (const [key, value] of Object.entries(right)) merged[key] = Object.hasOwn(left, key) ? mergeSelections(left[key], value) : value;
|
|
127
|
+
return merged;
|
|
128
|
+
}
|
|
129
|
+
function readLocation(location, props, options, resources) {
|
|
130
|
+
let value = location.from === "props" ? props : location.from === "options" ? options : resources;
|
|
131
|
+
for (const key of location.path) value = value?.[key];
|
|
132
|
+
return value;
|
|
133
|
+
}
|
|
134
|
+
function resolvePlan(plan, props, options, resources, resourceSelections) {
|
|
135
|
+
const result = {};
|
|
136
|
+
for (const [key, node] of Object.entries(plan.children)) if (node.kind === "object") {
|
|
137
|
+
if (node.guards.some((group) => group.every((location) => readLocation(location, props, options, resources) !== void 0))) result[key] = resolvePlan(node, props, options, resources, resourceSelections);
|
|
138
|
+
} else {
|
|
139
|
+
if (node.guards?.some((location) => readLocation(location, props, options, resources) === void 0)) continue;
|
|
140
|
+
const value = readLocation(node, props, options, resources);
|
|
141
|
+
if (node.selector) {
|
|
142
|
+
const selected = node.source === "resource" ? resourceSelections.get(node.selector) : node.selector(value);
|
|
143
|
+
result[key] = node.source === "resource" && isSingleResourceInput(selected) ? props.resources : selected;
|
|
144
|
+
} else if (value !== void 0 || node.definition?.visibility !== "optional") result[key] = value;
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
19
147
|
}
|
|
20
148
|
function createReusableBuilder(resources, options) {
|
|
21
149
|
const keys = resources.map((entry) => typeof entry === "string" ? entry : entry.value);
|
|
22
150
|
const resource = createProp.string.enum(keys);
|
|
151
|
+
const singleResource = createProp.string.enum(getResourcePaths(resources));
|
|
152
|
+
const resourcesAccessor = Object.assign(createLayoutResourcesAccessor(resources), { single() {
|
|
153
|
+
return { [singleResourceInput]: resources };
|
|
154
|
+
} });
|
|
23
155
|
function createReusable(definition) {
|
|
24
156
|
const include = definition.props?.include ?? {};
|
|
25
|
-
|
|
157
|
+
const select = definition.select ?? {};
|
|
158
|
+
if (definition.overlap !== void 0 && definition.overlap !== "preferProps" && definition.overlap !== "preferSelect") throw new LayoutConfigurationError("Unknown reusable overlap policy.");
|
|
26
159
|
const optionDefinitions = typeof options === "function" ? options({
|
|
27
160
|
name: createProp.string.literal("Reusable"),
|
|
28
161
|
resource
|
|
29
162
|
}) : options;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
163
|
+
function compile(selection, from) {
|
|
164
|
+
let plan = objectPlan({});
|
|
165
|
+
for (const [key, value] of Object.entries(selection)) {
|
|
166
|
+
let next;
|
|
167
|
+
if (key === "options") {
|
|
168
|
+
if (value !== true && typeof value !== "function" && (!value || typeof value !== "object" || Array.isArray(value))) throw new LayoutConfigurationError("Invalid reusable options selection.");
|
|
169
|
+
next = typeof value === "function" ? objectPlan({ options: {
|
|
170
|
+
kind: "value",
|
|
171
|
+
source: "option",
|
|
172
|
+
from: "options",
|
|
173
|
+
path: [],
|
|
174
|
+
selector: value
|
|
175
|
+
} }) : optionPlan(optionDefinitions, value, from);
|
|
176
|
+
} else if (key === "resources" && (value === true || typeof value === "function")) next = objectPlan({ resources: {
|
|
177
|
+
kind: "value",
|
|
178
|
+
source: "resource",
|
|
179
|
+
from: value === true && from === "props" ? "props" : "resources",
|
|
180
|
+
path: value === true && from === "props" ? ["resources"] : [],
|
|
181
|
+
selector: typeof value === "function" ? value : void 0,
|
|
182
|
+
definition: value === true && from === "props" ? createProp.array(resource) : void 0
|
|
183
|
+
} });
|
|
184
|
+
else throw new LayoutConfigurationError(`Invalid reusable source "${key}".`);
|
|
185
|
+
plan = mergePlans(plan, next);
|
|
186
|
+
}
|
|
187
|
+
return plan;
|
|
38
188
|
}
|
|
189
|
+
let included = compile(include, "props");
|
|
190
|
+
const custom = objectPlan(Object.fromEntries(Object.entries(definition.props?.custom ?? {}).map(([key, value]) => [key, {
|
|
191
|
+
kind: "value",
|
|
192
|
+
source: "custom",
|
|
193
|
+
from: "props",
|
|
194
|
+
path: [key],
|
|
195
|
+
definition: value
|
|
196
|
+
}])));
|
|
197
|
+
included = mergePlans(included, custom);
|
|
198
|
+
const selected = compile(select, "options");
|
|
199
|
+
const plan = mergePlans(included, selected, definition.overlap);
|
|
200
|
+
const callerDefinitions = planDefinitions(withoutSharedCallerValues(included, selected), "props");
|
|
201
|
+
const effectiveCallerDefinitions = planDefinitions(plan, "props");
|
|
202
|
+
const sources = mergeSelections(sourceSelection(include.options, true), sourceSelection(select.options, false));
|
|
203
|
+
const sourceDefinitions = sources === true ? optionDefinitions : planDefinitions(optionPlan(optionDefinitions, sources, "options"), "options");
|
|
204
|
+
const resourceSelectors = new Set([include.resources, select.resources].filter((selector) => typeof selector === "function"));
|
|
205
|
+
const needsOptions = Object.keys(sourceDefinitions).length > 0;
|
|
206
|
+
if (needsOptions && Object.hasOwn(callerDefinitions, "options")) throw new LayoutConfigurationError("Reusable prop \"options\" is reserved for source values.");
|
|
39
207
|
return function reusable(props = {}) {
|
|
40
|
-
validateProps(
|
|
41
|
-
|
|
208
|
+
validateProps(definition.overlap ? callerDefinitions : effectiveCallerDefinitions, props);
|
|
209
|
+
if (needsOptions && props.options !== void 0 && (props.options === null || typeof props.options !== "object" || Array.isArray(props.options))) throw new LayoutConfigurationError("Reusable source options must be an object.");
|
|
210
|
+
const values = props.options ?? {};
|
|
211
|
+
validateProps(sourceDefinitions, values);
|
|
212
|
+
const resourceSelections = /* @__PURE__ */ new Map();
|
|
213
|
+
for (const selector of resourceSelectors) {
|
|
214
|
+
const selected = selector(resourcesAccessor);
|
|
215
|
+
if (isSingleResourceInput(selected)) validateProps({ resources: singleResource }, props);
|
|
216
|
+
resourceSelections.set(selector, selected);
|
|
217
|
+
}
|
|
218
|
+
return definition.fn(resolvePlan(plan, props, values, resourcesAccessor, resourceSelections));
|
|
42
219
|
};
|
|
43
220
|
}
|
|
44
221
|
return createReusable;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-reusable.mjs","names":[],"sources":["../../src/create-config/create-reusable.ts"],"sourcesContent":["import {\n createProp,\n validateProps,\n type AnyBuiltPropDefinition,\n type ExtractDefinitionValue,\n type ResolvedBuiltPropShape,\n} from '@jfdevelops/react-layout-validator';\nimport type {\n InferredInProps,\n InPropsDefinition,\n InPropsObject,\n} from '../props';\nimport type { ResourceDefinition, ResourceEnum } from '../resource';\nimport { LayoutConfigurationError } from '../errors';\n\n/** Object definitions can be selected recursively; other definitions are leaves. */\nexport type ReusableOptionSelection<Props extends InPropsObject> = {\n [Key in keyof Props]?: Props[Key] extends {\n type: 'object';\n properties: infer Shape extends InPropsObject;\n }\n ? true | ReusableOptionSelection<Shape>\n : true;\n};\n\ntype OptionDefinitions<\n Resources extends readonly ResourceDefinition[],\n Options extends InPropsDefinition<Resources>,\n> = InferredInProps<\n Resources,\n Options\n> extends infer Props extends InPropsObject\n ? Props\n : never;\n\n/** Only data sources declared by the factory are available for selection. */\nexport type ReusableInclude<\n Resources extends readonly ResourceDefinition[],\n Options extends InPropsDefinition<Resources>,\n> = { resources?: true } & (keyof OptionDefinitions<\n Resources,\n Options\n> extends never\n ? {}\n : {\n options?:\n | true\n | ReusableOptionSelection<OptionDefinitions<Resources, Options>>;\n });\n\ntype SelectedOptionValue<\n Definition extends AnyBuiltPropDefinition,\n Selection,\n> = Selection extends true\n ? ExtractDefinitionValue<Definition>\n : Definition extends { properties: infer Shape extends InPropsObject }\n ? SelectedOptionProps<Shape, Selection>\n : never;\n\ntype SelectedOptionProps<Props extends InPropsObject, Selection> = {\n [Key in keyof Props &\n keyof Selection as Props[Key]['visibility'] extends 'required'\n ? Key\n : never]: SelectedOptionValue<Props[Key], Selection[Key]>;\n} & {\n [Key in keyof Props &\n keyof Selection as Props[Key]['visibility'] extends 'optional'\n ? Key\n : never]?: SelectedOptionValue<Props[Key], Selection[Key]>;\n};\n\n/** Options are flattened one level, so `options: { meta: true }` supplies `meta`. */\nexport type ReusableProps<\n Resources extends readonly ResourceDefinition[],\n Options extends InPropsDefinition<Resources>,\n Include,\n Custom extends InPropsObject,\n> = (Include extends { resources: true }\n ? { resources: ResourceEnum<Resources>[number][] }\n : {}) &\n (Include extends { options: infer Selection }\n ? Selection extends true\n ? ResolvedBuiltPropShape<OptionDefinitions<Resources, Options>>\n : SelectedOptionProps<OptionDefinitions<Resources, Options>, Selection>\n : {}) &\n ResolvedBuiltPropShape<Custom>;\n\n// Generic constraints alone accept extra keys on structurally compatible objects.\ntype ExactSelection<Selection, Allowed> = {\n [Key in keyof Selection]: Key extends keyof Allowed\n ? Selection[Key] extends object\n ? ExactSelection<Selection[Key], Exclude<Allowed[Key], true | undefined>>\n : Allowed[Key]\n : never;\n};\n\n/** Creates a validated ordinary function with the shared configuration's types. */\nexport type CreateReusable<\n Resources extends readonly ResourceDefinition[],\n Options extends InPropsDefinition<Resources>,\n> = <\n const Include extends ReusableInclude<Resources, Options> = {},\n const Custom extends InPropsObject = {},\n Result = unknown,\n>(definition: {\n props?: {\n include?: ReusableInclude<Resources, Options> &\n Include &\n ExactSelection<Include, ReusableInclude<Resources, Options>>;\n custom?: Custom;\n };\n fn: (props: ReusableProps<Resources, Options, Include, Custom>) => Result;\n}) => (\n ...args: {} extends ReusableProps<Resources, Options, Include, Custom>\n ? [props?: ReusableProps<Resources, Options, Include, Custom>]\n : [props: ReusableProps<Resources, Options, Include, Custom>]\n) => Result;\n\nfunction selectOptions(\n definitions: InPropsObject,\n selection: Record<string, unknown>,\n) {\n const selected: InPropsObject = {};\n for (const [key, include] of Object.entries(selection)) {\n const definition = definitions[key];\n if (!Object.hasOwn(definitions, key)) {\n throw new LayoutConfigurationError(`Unknown reusable option \"${key}\".`);\n }\n if (include === true) {\n selected[key] = definition;\n continue;\n }\n if (\n !include ||\n typeof include !== 'object' ||\n !('properties' in definition) ||\n !('type' in definition) ||\n definition.type !== 'object'\n ) {\n throw new LayoutConfigurationError(\n `Invalid reusable selection for \"${key}\".`,\n );\n }\n const nested = createProp.object(\n selectOptions(\n definition.properties as InPropsObject,\n include as Record<string, unknown>,\n ),\n );\n selected[key] =\n definition.visibility === 'optional' ? nested.optional() : nested;\n }\n return selected;\n}\n\nexport function createReusableBuilder<\n const Resources extends readonly ResourceDefinition[],\n Options extends InPropsDefinition<Resources>,\n>(resources: Resources, options: Options): CreateReusable<Resources, Options>;\nexport function createReusableBuilder(\n resources: readonly ResourceDefinition[],\n options: InPropsObject | ((...args: any[]) => InPropsObject),\n) {\n const keys = resources.map((entry) =>\n typeof entry === 'string' ? entry : entry.value,\n );\n const resource = createProp.string.enum(keys as [string, ...string[]]);\n\n function createReusable(definition: {\n props?: { include?: Record<string, unknown>; custom?: InPropsObject };\n fn: (props: Record<string, unknown>) => unknown;\n }) {\n const include = definition.props?.include ?? {};\n for (const key of Object.keys(include)) {\n if (key !== 'resources' && key !== 'options') {\n throw new LayoutConfigurationError(`Unknown reusable source \"${key}\".`);\n }\n }\n const optionDefinitions =\n typeof options === 'function'\n ? options({ name: createProp.string.literal('Reusable'), resource })\n : options;\n const selected =\n include.options === true\n ? optionDefinitions\n : include.options\n ? selectOptions(\n optionDefinitions,\n include.options as Record<string, unknown>,\n )\n : {};\n const definitions: InPropsObject = { ...selected };\n if (include.resources) {\n if (Object.hasOwn(definitions, 'resources')) {\n throw new LayoutConfigurationError(\n 'Reusable prop \"resources\" is selected more than once.',\n );\n }\n definitions.resources = createProp.array(resource);\n }\n for (const [key, custom] of Object.entries(\n definition.props?.custom ?? {},\n )) {\n if (Object.hasOwn(definitions, key)) {\n throw new LayoutConfigurationError(\n `Reusable prop \"${key}\" is selected more than once.`,\n );\n }\n definitions[key] = custom;\n }\n\n return function reusable(props: Record<string, unknown> = {}) {\n validateProps(definitions, props);\n return definition.fn(props);\n };\n }\n\n return createReusable as unknown;\n}\n"],"mappings":";;;;AAsHA,SAAS,cACP,aACA,WACA;CACA,MAAM,WAA0B,CAAC;CACjC,KAAK,MAAM,CAAC,KAAK,YAAY,OAAO,QAAQ,SAAS,GAAG;EACtD,MAAM,aAAa,YAAY;EAC/B,IAAI,CAAC,OAAO,OAAO,aAAa,GAAG,GACjC,MAAM,IAAI,yBAAyB,4BAA4B,IAAI,GAAG;EAExE,IAAI,YAAY,MAAM;GACpB,SAAS,OAAO;GAChB;EACF;EACA,IACE,CAAC,WACD,OAAO,YAAY,YACnB,EAAE,gBAAgB,eAClB,EAAE,UAAU,eACZ,WAAW,SAAS,UAEpB,MAAM,IAAI,yBACR,mCAAmC,IAAI,GACzC;EAEF,MAAM,SAAS,WAAW,OACxB,cACE,WAAW,YACX,OACF,CACF;EACA,SAAS,OACP,WAAW,eAAe,aAAa,OAAO,SAAS,IAAI;CAC/D;CACA,OAAO;AACT;AAMA,SAAgB,sBACd,WACA,SACA;CACA,MAAM,OAAO,UAAU,KAAK,UAC1B,OAAO,UAAU,WAAW,QAAQ,MAAM,KAC5C;CACA,MAAM,WAAW,WAAW,OAAO,KAAK,IAA6B;CAErE,SAAS,eAAe,YAGrB;EACD,MAAM,UAAU,WAAW,OAAO,WAAW,CAAC;EAC9C,KAAK,MAAM,OAAO,OAAO,KAAK,OAAO,GACnC,IAAI,QAAQ,eAAe,QAAQ,WACjC,MAAM,IAAI,yBAAyB,4BAA4B,IAAI,GAAG;EAG1E,MAAM,oBACJ,OAAO,YAAY,aACf,QAAQ;GAAE,MAAM,WAAW,OAAO,QAAQ,UAAU;GAAG;EAAS,CAAC,IACjE;EAUN,MAAM,cAA6B,EAAE,GARnC,QAAQ,YAAY,OAChB,oBACA,QAAQ,UACR,cACE,mBACA,QAAQ,OACV,IACA,CAAC,EAC0C;EACjD,IAAI,QAAQ,WAAW;GACrB,IAAI,OAAO,OAAO,aAAa,WAAW,GACxC,MAAM,IAAI,yBACR,yDACF;GAEF,YAAY,YAAY,WAAW,MAAM,QAAQ;EACnD;EACA,KAAK,MAAM,CAAC,KAAK,WAAW,OAAO,QACjC,WAAW,OAAO,UAAU,CAAC,CAC/B,GAAG;GACD,IAAI,OAAO,OAAO,aAAa,GAAG,GAChC,MAAM,IAAI,yBACR,kBAAkB,IAAI,8BACxB;GAEF,YAAY,OAAO;EACrB;EAEA,OAAO,SAAS,SAAS,QAAiC,CAAC,GAAG;GAC5D,cAAc,aAAa,KAAK;GAChC,OAAO,WAAW,GAAG,KAAK;EAC5B;CACF;CAEA,OAAO;AACT"}
|
|
1
|
+
{"version":3,"file":"create-reusable.mjs","names":[],"sources":["../../src/create-config/create-reusable.ts"],"sourcesContent":["import {\n createProp,\n validateProps,\n type AnyBuiltPropDefinition,\n} from '@jfdevelops/react-layout-validator';\nimport type { InPropsDefinition, InPropsObject, PropsContract } from '../props';\nimport type { ResourceDefinition } from '../resource';\nimport { LayoutConfigurationError } from '../errors';\nimport { createLayoutResourcesAccessor } from './define-layout';\nimport type { CreateReusable, ReusableOverlap } from './reusable-types';\nexport type * from './reusable-types';\nimport {\n singleResourceInput,\n isSingleResourceInput,\n getResourcePaths,\n} from './reusable-resource-input';\n\ntype RuntimeSelection = Record<string, unknown>;\ntype PlanLocation = { from: 'props' | 'options' | 'resources'; path: string[] };\ntype ValuePlan = PlanLocation & {\n kind: 'value';\n // Optional ancestors remain tied to the value's original source after merging.\n guards?: PlanLocation[];\n source: 'option' | 'resource' | 'custom';\n selector?: (value: any) => unknown;\n definition?: AnyBuiltPropDefinition;\n};\ntype ResourceSelector = NonNullable<ValuePlan['selector']>;\ntype ResourceSelections = Map<ResourceSelector, unknown>;\n\ntype ObjectPlan = {\n kind: 'object';\n children: Record<string, Plan>;\n optional: boolean;\n guards: PlanLocation[][];\n};\ntype Plan = ValuePlan | ObjectPlan;\n\nfunction objectPlan(\n children: Record<string, Plan>,\n optional = false,\n guards: PlanLocation[][] = [[]],\n): ObjectPlan {\n return { kind: 'object', children, optional, guards };\n}\n\nfunction optionPlan(\n definitions: InPropsObject,\n selection: unknown,\n from: 'props' | 'options',\n path: string[] = [],\n optionalPaths: string[][] = [],\n): ObjectPlan {\n const entries =\n selection === true\n ? Object.fromEntries(Object.keys(definitions).map((key) => [key, true]))\n : (selection as RuntimeSelection);\n const children: Record<string, Plan> = {};\n for (const [key, value] of Object.entries(entries ?? {})) {\n if (!Object.hasOwn(definitions, key))\n throw new LayoutConfigurationError(`Unknown reusable option \"${key}\".`);\n const definition = definitions[key];\n const location: PlanLocation = { from, path: [...path, key] };\n if (typeof value === 'function') {\n children[key] = {\n ...location,\n from: 'options',\n guards: optionalPaths.map((path) => ({ from: 'options', path })),\n kind: 'value',\n source: 'option',\n selector: value as ValuePlan['selector'],\n definition,\n };\n } else if (\n 'properties' in definition &&\n 'type' in definition &&\n definition.type === 'object' &&\n (value === true || (value && typeof value === 'object'))\n ) {\n const nested = optionPlan(\n definition.properties as InPropsObject,\n value,\n from,\n location.path,\n definition.visibility === 'optional'\n ? [...optionalPaths, location.path]\n : optionalPaths,\n );\n children[key] = {\n ...nested,\n optional: definition.visibility === 'optional',\n };\n } else if (value === true) {\n children[key] = {\n ...location,\n guards: optionalPaths.map((path) => ({ from, path })),\n kind: 'value',\n source: 'option',\n definition,\n };\n } else\n throw new LayoutConfigurationError(\n `Invalid reusable selection for \"${key}\".`,\n );\n }\n const origins = new Set<PlanLocation['from']>();\n function collectOrigins(node: Plan) {\n if (node.kind === 'value') origins.add(node.from);\n else Object.values(node.children).forEach(collectOrigins);\n }\n Object.values(children).forEach(collectOrigins);\n if (!origins.size) origins.add(from);\n return objectPlan(\n children,\n false,\n [...origins].map((origin) =>\n optionalPaths.map((path) => ({ from: origin, path })),\n ),\n );\n}\n\nfunction sameSelection(left: ValuePlan, right: ValuePlan) {\n return (\n left.source === right.source &&\n left.selector === right.selector &&\n left.path.join('.') === right.path.join('.') &&\n (left.source === 'option' || left.from === right.from)\n );\n}\n\nfunction mergePlans(\n left: ObjectPlan,\n right: ObjectPlan,\n overlap?: ReusableOverlap,\n path: string[] = [],\n): ObjectPlan {\n const children = { ...left.children };\n for (const [key, other] of Object.entries(right.children)) {\n const current = children[key];\n if (!current) {\n children[key] = other;\n continue;\n }\n if (current.kind === 'object' && other.kind === 'object') {\n children[key] = mergePlans(current, other, overlap, [...path, key]);\n } else if (\n current.kind === 'value' &&\n other.kind === 'value' &&\n sameSelection(current, other)\n ) {\n // A shared option selection uses one source value and executes only once.\n children[key] = other.from === 'options' ? other : current;\n } else if (overlap)\n children[key] = overlap === 'preferProps' ? current : other;\n else\n throw new LayoutConfigurationError(\n `Ambiguous reusable property \"${[...path, key].join(\n '.',\n )}\". Rename one result or set overlap to \"preferProps\" or \"preferSelect\".`,\n );\n }\n return {\n kind: 'object',\n children,\n optional: left.optional && right.optional,\n guards: [...left.guards, ...right.guards],\n };\n}\n\nfunction withoutSharedCallerValues(\n left: ObjectPlan,\n right: ObjectPlan,\n): ObjectPlan {\n const children = { ...left.children };\n for (const [key, other] of Object.entries(right.children)) {\n const current = children[key];\n if (current?.kind === 'object' && other.kind === 'object')\n children[key] = withoutSharedCallerValues(current, other);\n else if (\n current?.kind === 'value' &&\n other.kind === 'value' &&\n sameSelection(current, other) &&\n other.from === 'options'\n )\n delete children[key];\n }\n return { ...left, children };\n}\n\nfunction planDefinitions(\n plan: ObjectPlan,\n from: 'props' | 'options',\n): InPropsObject {\n const definitions: InPropsObject = {};\n for (const [key, value] of Object.entries(plan.children)) {\n if (value.kind === 'value') {\n if (value.from === from && value.definition)\n definitions[key] = value.definition;\n } else {\n const nested = planDefinitions(value, from);\n if (Object.keys(nested).length) {\n const definition = createProp.object(nested);\n definitions[key] = value.optional ? definition.optional() : definition;\n }\n }\n }\n return definitions;\n}\n\nfunction sourceSelection(\n selection: unknown,\n callbacksOnly: boolean,\n): true | RuntimeSelection {\n if (typeof selection === 'function') return true;\n if (selection === true) return callbacksOnly ? {} : true;\n const source: RuntimeSelection = {};\n for (const [key, value] of Object.entries(\n (selection ?? {}) as RuntimeSelection,\n )) {\n const nested = sourceSelection(value, callbacksOnly);\n if (nested === true || Object.keys(nested).length) source[key] = nested;\n }\n return source;\n}\n\nfunction mergeSelections(\n left: true | RuntimeSelection,\n right: true | RuntimeSelection,\n): true | RuntimeSelection {\n if (left === true || right === true) return true;\n const merged = { ...left };\n for (const [key, value] of Object.entries(right))\n merged[key] = Object.hasOwn(left, key)\n ? mergeSelections(\n left[key] as true | RuntimeSelection,\n value as true | RuntimeSelection,\n )\n : value;\n return merged;\n}\n\nfunction readLocation(\n location: PlanLocation,\n props: Record<string, unknown>,\n options: Record<string, unknown>,\n resources: unknown,\n) {\n let value: any =\n location.from === 'props'\n ? props\n : location.from === 'options'\n ? options\n : resources;\n for (const key of location.path) value = value?.[key];\n return value;\n}\n\nfunction resolvePlan(\n plan: ObjectPlan,\n props: Record<string, unknown>,\n options: Record<string, unknown>,\n resources: unknown,\n resourceSelections: ResourceSelections,\n) {\n const result: Record<string, unknown> = {};\n for (const [key, node] of Object.entries(plan.children)) {\n if (node.kind === 'object') {\n if (\n node.guards.some((group) =>\n group.every(\n (location) =>\n readLocation(location, props, options, resources) !== undefined,\n ),\n )\n ) {\n result[key] = resolvePlan(\n node,\n props,\n options,\n resources,\n resourceSelections,\n );\n }\n } else {\n if (\n node.guards?.some(\n (location) =>\n readLocation(location, props, options, resources) === undefined,\n )\n )\n continue;\n const value = readLocation(node, props, options, resources);\n if (node.selector) {\n const selected =\n node.source === 'resource'\n ? resourceSelections.get(node.selector)\n : node.selector(value);\n result[key] =\n node.source === 'resource' && isSingleResourceInput(selected)\n ? props.resources\n : selected;\n } else if (\n value !== undefined ||\n node.definition?.visibility !== 'optional'\n )\n result[key] = value;\n }\n }\n return result;\n}\n\nexport function createReusableBuilder<\n const Resources extends readonly ResourceDefinition[],\n Options extends InPropsDefinition<Resources>,\n>(resources: Resources, options: Options): CreateReusable<Resources, Options>;\nexport function createReusableBuilder(\n resources: readonly ResourceDefinition[],\n options: InPropsObject | ((...args: any[]) => InPropsObject),\n) {\n const keys = resources.map((entry) =>\n typeof entry === 'string' ? entry : entry.value,\n );\n const resource = createProp.string.enum(keys as [string, ...string[]]);\n const singleResource = createProp.string.enum(\n getResourcePaths(resources) as [string, ...string[]],\n );\n const resourcesAccessor = Object.assign(\n createLayoutResourcesAccessor(resources),\n {\n single() {\n return { [singleResourceInput]: resources };\n },\n },\n );\n\n function createReusable(definition: {\n props?: PropsContract<RuntimeSelection, InPropsObject>;\n select?: RuntimeSelection;\n overlap?: ReusableOverlap;\n fn: (props: Record<string, unknown>) => unknown;\n }) {\n const include = definition.props?.include ?? {};\n const select = definition.select ?? {};\n if (\n definition.overlap !== undefined &&\n definition.overlap !== 'preferProps' &&\n definition.overlap !== 'preferSelect'\n ) {\n throw new LayoutConfigurationError('Unknown reusable overlap policy.');\n }\n const optionDefinitions =\n typeof options === 'function'\n ? options({ name: createProp.string.literal('Reusable'), resource })\n : options;\n\n function compile(selection: RuntimeSelection, from: 'props' | 'options') {\n let plan = objectPlan({});\n for (const [key, value] of Object.entries(selection)) {\n let next: ObjectPlan;\n if (key === 'options') {\n if (\n value !== true &&\n typeof value !== 'function' &&\n (!value || typeof value !== 'object' || Array.isArray(value))\n ) {\n throw new LayoutConfigurationError(\n 'Invalid reusable options selection.',\n );\n }\n next =\n typeof value === 'function'\n ? objectPlan({\n options: {\n kind: 'value',\n source: 'option',\n from: 'options',\n path: [],\n selector: value as ValuePlan['selector'],\n },\n })\n : optionPlan(optionDefinitions, value, from);\n } else if (\n key === 'resources' &&\n (value === true || typeof value === 'function')\n ) {\n next = objectPlan({\n resources: {\n kind: 'value',\n source: 'resource',\n from: value === true && from === 'props' ? 'props' : 'resources',\n path: value === true && from === 'props' ? ['resources'] : [],\n selector:\n typeof value === 'function'\n ? (value as ValuePlan['selector'])\n : undefined,\n definition:\n value === true && from === 'props'\n ? createProp.array(resource)\n : undefined,\n },\n });\n } else\n throw new LayoutConfigurationError(\n `Invalid reusable source \"${key}\".`,\n );\n plan = mergePlans(plan, next);\n }\n return plan;\n }\n\n let included = compile(include, 'props');\n const custom = objectPlan(\n Object.fromEntries(\n Object.entries(definition.props?.custom ?? {}).map(([key, value]) => [\n key,\n {\n kind: 'value',\n source: 'custom',\n from: 'props',\n path: [key],\n definition: value,\n } as ValuePlan,\n ]),\n ),\n );\n included = mergePlans(included, custom);\n const selected = compile(select, 'options');\n const plan = mergePlans(included, selected, definition.overlap);\n const callerDefinitions = planDefinitions(\n withoutSharedCallerValues(included, selected),\n 'props',\n );\n // Identical true selections supplied by select are removed from the caller props contract.\n const effectiveCallerDefinitions = planDefinitions(plan, 'props');\n const sources = mergeSelections(\n sourceSelection(include.options, true),\n sourceSelection(select.options, false),\n );\n const sourceDefinitions =\n sources === true\n ? optionDefinitions\n : planDefinitions(\n optionPlan(optionDefinitions, sources, 'options'),\n 'options',\n );\n const resourceSelectors = new Set(\n [include.resources, select.resources].filter(\n (selector): selector is ResourceSelector =>\n typeof selector === 'function',\n ),\n );\n const needsOptions = Object.keys(sourceDefinitions).length > 0;\n if (needsOptions && Object.hasOwn(callerDefinitions, 'options')) {\n throw new LayoutConfigurationError(\n 'Reusable prop \"options\" is reserved for source values.',\n );\n }\n\n return function reusable(props: Record<string, unknown> = {}) {\n // Validate configured caller props too when an explicit overlap policy discards their output.\n const definitions = definition.overlap\n ? callerDefinitions\n : effectiveCallerDefinitions;\n validateProps(definitions, props);\n if (\n needsOptions &&\n props.options !== undefined &&\n (props.options === null ||\n typeof props.options !== 'object' ||\n Array.isArray(props.options))\n ) {\n throw new LayoutConfigurationError(\n 'Reusable source options must be an object.',\n );\n }\n const values = (props.options ?? {}) as Record<string, unknown>;\n validateProps(sourceDefinitions, values);\n // Resource callbacks also declare caller inputs, independently of overlap precedence.\n const resourceSelections: ResourceSelections = new Map();\n for (const selector of resourceSelectors) {\n const selected = selector(resourcesAccessor);\n if (isSingleResourceInput(selected))\n validateProps({ resources: singleResource }, props);\n resourceSelections.set(selector, selected);\n }\n return definition.fn(\n resolvePlan(plan, props, values, resourcesAccessor, resourceSelections),\n );\n };\n }\n return createReusable as unknown;\n}\n"],"mappings":";;;;;;AAsCA,SAAS,WACP,UACA,WAAW,OACX,SAA2B,CAAC,CAAC,CAAC,GAClB;CACZ,OAAO;EAAE,MAAM;EAAU;EAAU;EAAU;CAAO;AACtD;AAEA,SAAS,WACP,aACA,WACA,MACA,OAAiB,CAAC,GAClB,gBAA4B,CAAC,GACjB;CACZ,MAAM,UACJ,cAAc,OACV,OAAO,YAAY,OAAO,KAAK,WAAW,EAAE,KAAK,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC,IACpE;CACP,MAAM,WAAiC,CAAC;CACxC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,WAAW,CAAC,CAAC,GAAG;EACxD,IAAI,CAAC,OAAO,OAAO,aAAa,GAAG,GACjC,MAAM,IAAI,yBAAyB,4BAA4B,IAAI,GAAG;EACxE,MAAM,aAAa,YAAY;EAC/B,MAAM,WAAyB;GAAE;GAAM,MAAM,CAAC,GAAG,MAAM,GAAG;EAAE;EAC5D,IAAI,OAAO,UAAU,YACnB,SAAS,OAAO;GACd,GAAG;GACH,MAAM;GACN,QAAQ,cAAc,KAAK,UAAU;IAAE,MAAM;IAAW;GAAK,EAAE;GAC/D,MAAM;GACN,QAAQ;GACR,UAAU;GACV;EACF;OACK,IACL,gBAAgB,cAChB,UAAU,cACV,WAAW,SAAS,aACnB,UAAU,QAAS,SAAS,OAAO,UAAU,WAW9C,SAAS,OAAO;GACd,GAVa,WACb,WAAW,YACX,OACA,MACA,SAAS,MACT,WAAW,eAAe,aACtB,CAAC,GAAG,eAAe,SAAS,IAAI,IAChC,aAGI;GACR,UAAU,WAAW,eAAe;EACtC;OACK,IAAI,UAAU,MACnB,SAAS,OAAO;GACd,GAAG;GACH,QAAQ,cAAc,KAAK,UAAU;IAAE;IAAM;GAAK,EAAE;GACpD,MAAM;GACN,QAAQ;GACR;EACF;OAEA,MAAM,IAAI,yBACR,mCAAmC,IAAI,GACzC;CACJ;CACA,MAAM,0BAAU,IAAI,IAA0B;CAC9C,SAAS,eAAe,MAAY;EAClC,IAAI,KAAK,SAAS,SAAS,QAAQ,IAAI,KAAK,IAAI;OAC3C,OAAO,OAAO,KAAK,QAAQ,EAAE,QAAQ,cAAc;CAC1D;CACA,OAAO,OAAO,QAAQ,EAAE,QAAQ,cAAc;CAC9C,IAAI,CAAC,QAAQ,MAAM,QAAQ,IAAI,IAAI;CACnC,OAAO,WACL,UACA,OACA,CAAC,GAAG,OAAO,EAAE,KAAK,WAChB,cAAc,KAAK,UAAU;EAAE,MAAM;EAAQ;CAAK,EAAE,CACtD,CACF;AACF;AAEA,SAAS,cAAc,MAAiB,OAAkB;CACxD,OACE,KAAK,WAAW,MAAM,UACtB,KAAK,aAAa,MAAM,YACxB,KAAK,KAAK,KAAK,GAAG,MAAM,MAAM,KAAK,KAAK,GAAG,MAC1C,KAAK,WAAW,YAAY,KAAK,SAAS,MAAM;AAErD;AAEA,SAAS,WACP,MACA,OACA,SACA,OAAiB,CAAC,GACN;CACZ,MAAM,WAAW,EAAE,GAAG,KAAK,SAAS;CACpC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,QAAQ,GAAG;EACzD,MAAM,UAAU,SAAS;EACzB,IAAI,CAAC,SAAS;GACZ,SAAS,OAAO;GAChB;EACF;EACA,IAAI,QAAQ,SAAS,YAAY,MAAM,SAAS,UAC9C,SAAS,OAAO,WAAW,SAAS,OAAO,SAAS,CAAC,GAAG,MAAM,GAAG,CAAC;OAC7D,IACL,QAAQ,SAAS,WACjB,MAAM,SAAS,WACf,cAAc,SAAS,KAAK,GAG5B,SAAS,OAAO,MAAM,SAAS,YAAY,QAAQ;OAC9C,IAAI,SACT,SAAS,OAAO,YAAY,gBAAgB,UAAU;OAEtD,MAAM,IAAI,yBACR,gCAAgC,CAAC,GAAG,MAAM,GAAG,EAAE,KAC7C,GACF,EAAE,wEACJ;CACJ;CACA,OAAO;EACL,MAAM;EACN;EACA,UAAU,KAAK,YAAY,MAAM;EACjC,QAAQ,CAAC,GAAG,KAAK,QAAQ,GAAG,MAAM,MAAM;CAC1C;AACF;AAEA,SAAS,0BACP,MACA,OACY;CACZ,MAAM,WAAW,EAAE,GAAG,KAAK,SAAS;CACpC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,QAAQ,GAAG;EACzD,MAAM,UAAU,SAAS;EACzB,IAAI,SAAS,SAAS,YAAY,MAAM,SAAS,UAC/C,SAAS,OAAO,0BAA0B,SAAS,KAAK;OACrD,IACH,SAAS,SAAS,WAClB,MAAM,SAAS,WACf,cAAc,SAAS,KAAK,KAC5B,MAAM,SAAS,WAEf,OAAO,SAAS;CACpB;CACA,OAAO;EAAE,GAAG;EAAM;CAAS;AAC7B;AAEA,SAAS,gBACP,MACA,MACe;CACf,MAAM,cAA6B,CAAC;CACpC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,QAAQ,GACrD,IAAI,MAAM,SAAS,SACjB;MAAI,MAAM,SAAS,QAAQ,MAAM,YAC/B,YAAY,OAAO,MAAM;CAAU,OAChC;EACL,MAAM,SAAS,gBAAgB,OAAO,IAAI;EAC1C,IAAI,OAAO,KAAK,MAAM,EAAE,QAAQ;GAC9B,MAAM,aAAa,WAAW,OAAO,MAAM;GAC3C,YAAY,OAAO,MAAM,WAAW,WAAW,SAAS,IAAI;EAC9D;CACF;CAEF,OAAO;AACT;AAEA,SAAS,gBACP,WACA,eACyB;CACzB,IAAI,OAAO,cAAc,YAAY,OAAO;CAC5C,IAAI,cAAc,MAAM,OAAO,gBAAgB,CAAC,IAAI;CACpD,MAAM,SAA2B,CAAC;CAClC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAC/B,aAAa,CAAC,CACjB,GAAG;EACD,MAAM,SAAS,gBAAgB,OAAO,aAAa;EACnD,IAAI,WAAW,QAAQ,OAAO,KAAK,MAAM,EAAE,QAAQ,OAAO,OAAO;CACnE;CACA,OAAO;AACT;AAEA,SAAS,gBACP,MACA,OACyB;CACzB,IAAI,SAAS,QAAQ,UAAU,MAAM,OAAO;CAC5C,MAAM,SAAS,EAAE,GAAG,KAAK;CACzB,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAC7C,OAAO,OAAO,OAAO,OAAO,MAAM,GAAG,IACjC,gBACE,KAAK,MACL,KACF,IACA;CACN,OAAO;AACT;AAEA,SAAS,aACP,UACA,OACA,SACA,WACA;CACA,IAAI,QACF,SAAS,SAAS,UACd,QACA,SAAS,SAAS,YAClB,UACA;CACN,KAAK,MAAM,OAAO,SAAS,MAAM,QAAQ,QAAQ;CACjD,OAAO;AACT;AAEA,SAAS,YACP,MACA,OACA,SACA,WACA,oBACA;CACA,MAAM,SAAkC,CAAC;CACzC,KAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,KAAK,QAAQ,GACpD,IAAI,KAAK,SAAS,UAChB;MACE,KAAK,OAAO,MAAM,UAChB,MAAM,OACH,aACC,aAAa,UAAU,OAAO,SAAS,SAAS,MAAM,MAC1D,CACF,GAEA,OAAO,OAAO,YACZ,MACA,OACA,SACA,WACA,kBACF;CACF,OACK;EACL,IACE,KAAK,QAAQ,MACV,aACC,aAAa,UAAU,OAAO,SAAS,SAAS,MAAM,MAC1D,GAEA;EACF,MAAM,QAAQ,aAAa,MAAM,OAAO,SAAS,SAAS;EAC1D,IAAI,KAAK,UAAU;GACjB,MAAM,WACJ,KAAK,WAAW,aACZ,mBAAmB,IAAI,KAAK,QAAQ,IACpC,KAAK,SAAS,KAAK;GACzB,OAAO,OACL,KAAK,WAAW,cAAc,sBAAsB,QAAQ,IACxD,MAAM,YACN;EACR,OAAO,IACL,UAAU,UACV,KAAK,YAAY,eAAe,YAEhC,OAAO,OAAO;CAClB;CAEF,OAAO;AACT;AAMA,SAAgB,sBACd,WACA,SACA;CACA,MAAM,OAAO,UAAU,KAAK,UAC1B,OAAO,UAAU,WAAW,QAAQ,MAAM,KAC5C;CACA,MAAM,WAAW,WAAW,OAAO,KAAK,IAA6B;CACrE,MAAM,iBAAiB,WAAW,OAAO,KACvC,iBAAiB,SAAS,CAC5B;CACA,MAAM,oBAAoB,OAAO,OAC/B,8BAA8B,SAAS,GACvC,EACE,SAAS;EACP,OAAO,GAAG,sBAAsB,UAAU;CAC5C,EACF,CACF;CAEA,SAAS,eAAe,YAKrB;EACD,MAAM,UAAU,WAAW,OAAO,WAAW,CAAC;EAC9C,MAAM,SAAS,WAAW,UAAU,CAAC;EACrC,IACE,WAAW,YAAY,UACvB,WAAW,YAAY,iBACvB,WAAW,YAAY,gBAEvB,MAAM,IAAI,yBAAyB,kCAAkC;EAEvE,MAAM,oBACJ,OAAO,YAAY,aACf,QAAQ;GAAE,MAAM,WAAW,OAAO,QAAQ,UAAU;GAAG;EAAS,CAAC,IACjE;EAEN,SAAS,QAAQ,WAA6B,MAA2B;GACvE,IAAI,OAAO,WAAW,CAAC,CAAC;GACxB,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,SAAS,GAAG;IACpD,IAAI;IACJ,IAAI,QAAQ,WAAW;KACrB,IACE,UAAU,QACV,OAAO,UAAU,eAChB,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,IAE3D,MAAM,IAAI,yBACR,qCACF;KAEF,OACE,OAAO,UAAU,aACb,WAAW,EACT,SAAS;MACP,MAAM;MACN,QAAQ;MACR,MAAM;MACN,MAAM,CAAC;MACP,UAAU;KACZ,EACF,CAAC,IACD,WAAW,mBAAmB,OAAO,IAAI;IACjD,OAAO,IACL,QAAQ,gBACP,UAAU,QAAQ,OAAO,UAAU,aAEpC,OAAO,WAAW,EAChB,WAAW;KACT,MAAM;KACN,QAAQ;KACR,MAAM,UAAU,QAAQ,SAAS,UAAU,UAAU;KACrD,MAAM,UAAU,QAAQ,SAAS,UAAU,CAAC,WAAW,IAAI,CAAC;KAC5D,UACE,OAAO,UAAU,aACZ,QACD;KACN,YACE,UAAU,QAAQ,SAAS,UACvB,WAAW,MAAM,QAAQ,IACzB;IACR,EACF,CAAC;SAED,MAAM,IAAI,yBACR,4BAA4B,IAAI,GAClC;IACF,OAAO,WAAW,MAAM,IAAI;GAC9B;GACA,OAAO;EACT;EAEA,IAAI,WAAW,QAAQ,SAAS,OAAO;EACvC,MAAM,SAAS,WACb,OAAO,YACL,OAAO,QAAQ,WAAW,OAAO,UAAU,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,WAAW,CACnE,KACA;GACE,MAAM;GACN,QAAQ;GACR,MAAM;GACN,MAAM,CAAC,GAAG;GACV,YAAY;EACd,CACF,CAAC,CACH,CACF;EACA,WAAW,WAAW,UAAU,MAAM;EACtC,MAAM,WAAW,QAAQ,QAAQ,SAAS;EAC1C,MAAM,OAAO,WAAW,UAAU,UAAU,WAAW,OAAO;EAC9D,MAAM,oBAAoB,gBACxB,0BAA0B,UAAU,QAAQ,GAC5C,OACF;EAEA,MAAM,6BAA6B,gBAAgB,MAAM,OAAO;EAChE,MAAM,UAAU,gBACd,gBAAgB,QAAQ,SAAS,IAAI,GACrC,gBAAgB,OAAO,SAAS,KAAK,CACvC;EACA,MAAM,oBACJ,YAAY,OACR,oBACA,gBACE,WAAW,mBAAmB,SAAS,SAAS,GAChD,SACF;EACN,MAAM,oBAAoB,IAAI,IAC5B,CAAC,QAAQ,WAAW,OAAO,SAAS,EAAE,QACnC,aACC,OAAO,aAAa,UACxB,CACF;EACA,MAAM,eAAe,OAAO,KAAK,iBAAiB,EAAE,SAAS;EAC7D,IAAI,gBAAgB,OAAO,OAAO,mBAAmB,SAAS,GAC5D,MAAM,IAAI,yBACR,0DACF;EAGF,OAAO,SAAS,SAAS,QAAiC,CAAC,GAAG;GAK5D,cAHoB,WAAW,UAC3B,oBACA,4BACuB,KAAK;GAChC,IACE,gBACA,MAAM,YAAY,WACjB,MAAM,YAAY,QACjB,OAAO,MAAM,YAAY,YACzB,MAAM,QAAQ,MAAM,OAAO,IAE7B,MAAM,IAAI,yBACR,4CACF;GAEF,MAAM,SAAU,MAAM,WAAW,CAAC;GAClC,cAAc,mBAAmB,MAAM;GAEvC,MAAM,qCAAyC,IAAI,IAAI;GACvD,KAAK,MAAM,YAAY,mBAAmB;IACxC,MAAM,WAAW,SAAS,iBAAiB;IAC3C,IAAI,sBAAsB,QAAQ,GAChC,cAAc,EAAE,WAAW,eAAe,GAAG,KAAK;IACpD,mBAAmB,IAAI,UAAU,QAAQ;GAC3C;GACA,OAAO,WAAW,GAChB,YAAY,MAAM,OAAO,QAAQ,mBAAmB,kBAAkB,CACxE;EACF;CACF;CACA,OAAO;AACT"}
|
|
@@ -10,7 +10,8 @@ import { IsSubResourceKey, IsSubResourceKeyOptions, IsSubResourceKeyResult } fro
|
|
|
10
10
|
import { ComponentTypes, CreateResourceConfigFn, CreateResourceConfigForResource, CreatedResourceConfig, GetComponent, GetComponentAtBound, GetComponentForResource, GetComponentForResourceOptions, GetComponentOptions, GetComponentOptionsForResource, ResourceConfigFragment, ResourceConfigPath, ResourceFromGetComponentBound, SubResourceFromGetComponentBound, ValidateForResourceBound } from "./get-component.cjs";
|
|
11
11
|
import { CreateResourceLinkConfig, CreateResourceLinkGroupInput, CreateResourceLinkGroupOptions, CreateResourceLinkOptions, CreateResourceLinksFn, CreateResourceLinksWithGroups, CreateResourceLinksWithGroupsFn, CreateResourceLinksWithGroupsResult, CreateResourceMap, CreateResourceMapFn, CreatedResourceHref, CreatedResourceLink, CreatedResourceLinkBase, CreatedResourceMap, DefineResourceIconFn, DefineResourceIconInputHelpers, DefineResourceIconInputResult, FindResolvedResourceGroupResult, FindResourceGroupResult, InferHashFromResourceLinkHref, ResolveResourceIconInput, ResolvedResourceLinksWithGroups, ResolvedResourceLinksWithGroupsResult, ResourceAnchorLinkFn, ResourceIcon, ResourceIconFn, ResourceLinkHref, ValidateResource } from "./create-resource-links.cjs";
|
|
12
12
|
import { ContextualInlineRenderState, ContextualInlineRenderStates, CreateResourceLayoutFn, CreateResourceLayoutMakeComposableOptions, CreateResourceLayoutWithLayoutOptions, CreateViewMapBuiltInRenderStatesOptions, CreateViewMapFunctionRenderOptions, CreateViewMapInlineRenderStatesOptions, CreateViewMapOptions, CreateViewMapRenderStatesOptions, DefineResourceLayout, DefineResourceLayoutFn, DefineResourceLayoutForResources, DefineResourceLayoutForResourcesFactory, DefineResourceLayoutWithLayoutFn, DefineResourcesFn, DefinedResourceLayout, DefinedResourceLayoutWithShell, LayoutDefinition, LayoutIncludeProps, LayoutRenderResourcesAccessor, LayoutResourcesAccessor, ResourceLayoutProvider, ResourceLayoutProviderProps, ResourceLayoutShellComponent, ResourceLayoutShellProps, ResourceSelection, ShellLayoutDefinition, ShellRenderContext, TypedBuiltInRenderStates, TypedInlineRenderState, defineResourceLayout } from "./define-layout.cjs";
|
|
13
|
-
import {
|
|
13
|
+
import { ReusableResourcesAccessor, SingleResourceInput } from "./reusable-resource-input.cjs";
|
|
14
|
+
import { CreateReusable, ReusableArguments, ReusableDefinition, ReusableFunction, ReusableInclude, ReusableInput, ReusableOptionSelection, ReusableOverlap, ReusableProps, ReusableResolved, ReusableSelected } from "./reusable-types.cjs";
|
|
14
15
|
import { LazyResourceLayoutComponent, LazyResourceLayoutOptions } from "./lazy-resource-layout.cjs";
|
|
15
16
|
import { BoundDefineResourceLayout, CreateDefinedResourceLayoutOptions, CreateDefinedResourceLayoutResult, DefineLazyDefaults, DefinedResourceLayoutInput, NonEmptyResources, createDefinedResourceLayout } from "./create-defined-resource-layout.cjs";
|
|
16
17
|
import { ResourceLayoutShellPublisher } from "./shell-context.cjs";
|
|
@@ -10,7 +10,8 @@ import { IsSubResourceKey, IsSubResourceKeyOptions, IsSubResourceKeyResult } fro
|
|
|
10
10
|
import { ComponentTypes, CreateResourceConfigFn, CreateResourceConfigForResource, CreatedResourceConfig, GetComponent, GetComponentAtBound, GetComponentForResource, GetComponentForResourceOptions, GetComponentOptions, GetComponentOptionsForResource, ResourceConfigFragment, ResourceConfigPath, ResourceFromGetComponentBound, SubResourceFromGetComponentBound, ValidateForResourceBound } from "./get-component.mjs";
|
|
11
11
|
import { CreateResourceLinkConfig, CreateResourceLinkGroupInput, CreateResourceLinkGroupOptions, CreateResourceLinkOptions, CreateResourceLinksFn, CreateResourceLinksWithGroups, CreateResourceLinksWithGroupsFn, CreateResourceLinksWithGroupsResult, CreateResourceMap, CreateResourceMapFn, CreatedResourceHref, CreatedResourceLink, CreatedResourceLinkBase, CreatedResourceMap, DefineResourceIconFn, DefineResourceIconInputHelpers, DefineResourceIconInputResult, FindResolvedResourceGroupResult, FindResourceGroupResult, InferHashFromResourceLinkHref, ResolveResourceIconInput, ResolvedResourceLinksWithGroups, ResolvedResourceLinksWithGroupsResult, ResourceAnchorLinkFn, ResourceIcon, ResourceIconFn, ResourceLinkHref, ValidateResource } from "./create-resource-links.mjs";
|
|
12
12
|
import { ContextualInlineRenderState, ContextualInlineRenderStates, CreateResourceLayoutFn, CreateResourceLayoutMakeComposableOptions, CreateResourceLayoutWithLayoutOptions, CreateViewMapBuiltInRenderStatesOptions, CreateViewMapFunctionRenderOptions, CreateViewMapInlineRenderStatesOptions, CreateViewMapOptions, CreateViewMapRenderStatesOptions, DefineResourceLayout, DefineResourceLayoutFn, DefineResourceLayoutForResources, DefineResourceLayoutForResourcesFactory, DefineResourceLayoutWithLayoutFn, DefineResourcesFn, DefinedResourceLayout, DefinedResourceLayoutWithShell, LayoutDefinition, LayoutIncludeProps, LayoutRenderResourcesAccessor, LayoutResourcesAccessor, ResourceLayoutProvider, ResourceLayoutProviderProps, ResourceLayoutShellComponent, ResourceLayoutShellProps, ResourceSelection, ShellLayoutDefinition, ShellRenderContext, TypedBuiltInRenderStates, TypedInlineRenderState, defineResourceLayout } from "./define-layout.mjs";
|
|
13
|
-
import {
|
|
13
|
+
import { ReusableResourcesAccessor, SingleResourceInput } from "./reusable-resource-input.mjs";
|
|
14
|
+
import { CreateReusable, ReusableArguments, ReusableDefinition, ReusableFunction, ReusableInclude, ReusableInput, ReusableOptionSelection, ReusableOverlap, ReusableProps, ReusableResolved, ReusableSelected } from "./reusable-types.mjs";
|
|
14
15
|
import { LazyResourceLayoutComponent, LazyResourceLayoutOptions } from "./lazy-resource-layout.mjs";
|
|
15
16
|
import { BoundDefineResourceLayout, CreateDefinedResourceLayoutOptions, CreateDefinedResourceLayoutResult, DefineLazyDefaults, DefinedResourceLayoutInput, NonEmptyResources, createDefinedResourceLayout } from "./create-defined-resource-layout.mjs";
|
|
16
17
|
import { ResourceLayoutShellPublisher } from "./shell-context.mjs";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge-layout-props.cjs","names":[],"sources":["../../src/create-config/merge-layout-props.ts"],"sourcesContent":["/** Merge contracts by section and prop key; the closest declaration wins. */\nexport function mergeLayoutProps<\n A extends
|
|
1
|
+
{"version":3,"file":"merge-layout-props.cjs","names":[],"sources":["../../src/create-config/merge-layout-props.ts"],"sourcesContent":["import type { PropsContract } from '../props';\n\n/** Merge contracts by section and prop key; the closest declaration wins. */\nexport function mergeLayoutProps<\n A extends PropsContract | undefined,\n B extends PropsContract | undefined\n>(base: A, local: B) {\n if (!base && !local) return undefined;\n return {\n include: { ...base?.include, ...local?.include },\n custom: { ...base?.custom, ...local?.custom },\n } as {\n include: NonNullable<A>['include'] & NonNullable<B>['include'];\n custom: NonNullable<A>['custom'] & NonNullable<B>['custom'];\n };\n}\n"],"mappings":";;;AAGA,SAAgB,iBAGd,MAAS,OAAU;CACnB,IAAI,CAAC,QAAQ,CAAC,OAAO,OAAO;CAC5B,OAAO;EACL,SAAS;GAAE,GAAG,MAAM;GAAS,GAAG,OAAO;EAAQ;EAC/C,QAAQ;GAAE,GAAG,MAAM;GAAQ,GAAG,OAAO;EAAO;CAC9C;AAIF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge-layout-props.mjs","names":[],"sources":["../../src/create-config/merge-layout-props.ts"],"sourcesContent":["/** Merge contracts by section and prop key; the closest declaration wins. */\nexport function mergeLayoutProps<\n A extends
|
|
1
|
+
{"version":3,"file":"merge-layout-props.mjs","names":[],"sources":["../../src/create-config/merge-layout-props.ts"],"sourcesContent":["import type { PropsContract } from '../props';\n\n/** Merge contracts by section and prop key; the closest declaration wins. */\nexport function mergeLayoutProps<\n A extends PropsContract | undefined,\n B extends PropsContract | undefined\n>(base: A, local: B) {\n if (!base && !local) return undefined;\n return {\n include: { ...base?.include, ...local?.include },\n custom: { ...base?.custom, ...local?.custom },\n } as {\n include: NonNullable<A>['include'] & NonNullable<B>['include'];\n custom: NonNullable<A>['custom'] & NonNullable<B>['custom'];\n };\n}\n"],"mappings":";;AAGA,SAAgB,iBAGd,MAAS,OAAU;CACnB,IAAI,CAAC,QAAQ,CAAC,OAAO,OAAO;CAC5B,OAAO;EACL,SAAS;GAAE,GAAG,MAAM;GAAS,GAAG,OAAO;EAAQ;EAC/C,QAAQ;GAAE,GAAG,MAAM;GAAQ,GAAG,OAAO;EAAO;CAC9C;AAIF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/create-config/reusable-resource-input.ts
|
|
3
|
+
const singleResourceInput = Symbol("react-layout.single-resource-input");
|
|
4
|
+
function isSingleResourceInput(value) {
|
|
5
|
+
return value !== null && typeof value === "object" && singleResourceInput in value;
|
|
6
|
+
}
|
|
7
|
+
function getResourcePaths(resources, prefix = "") {
|
|
8
|
+
const paths = [];
|
|
9
|
+
for (const resource of resources) {
|
|
10
|
+
const key = typeof resource === "string" ? resource : resource.value;
|
|
11
|
+
const path = prefix ? `${prefix}.${key}` : key;
|
|
12
|
+
paths.push(path);
|
|
13
|
+
if (typeof resource !== "string") paths.push(...getResourcePaths(resource.subResources, path));
|
|
14
|
+
}
|
|
15
|
+
return paths;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
exports.getResourcePaths = getResourcePaths;
|
|
20
|
+
exports.isSingleResourceInput = isSingleResourceInput;
|
|
21
|
+
exports.singleResourceInput = singleResourceInput;
|
|
22
|
+
//# sourceMappingURL=reusable-resource-input.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reusable-resource-input.cjs","names":[],"sources":["../../src/create-config/reusable-resource-input.ts"],"sourcesContent":["import type { LayoutResourcesAccessor } from './define-layout';\nimport type { ResourceDefinition } from '../resource';\n\nexport const singleResourceInput = Symbol('react-layout.single-resource-input');\n\n/** Describes one configured resource path supplied by the reusable's caller. */\nexport type SingleResourceInput<\n Resources extends readonly ResourceDefinition[],\n> = {\n readonly [singleResourceInput]: Resources;\n};\n\n/** Resource selector capabilities available to reusable definitions. */\nexport type ReusableResourcesAccessor<\n Resources extends readonly ResourceDefinition[],\n> = LayoutResourcesAccessor<Resources> & {\n single(): SingleResourceInput<Resources>;\n};\n\nexport function isSingleResourceInput(\n value: unknown,\n): value is SingleResourceInput<readonly ResourceDefinition[]> {\n return (\n value !== null && typeof value === 'object' && singleResourceInput in value\n );\n}\n\nexport function getResourcePaths(\n resources: readonly ResourceDefinition[],\n prefix = '',\n) {\n const paths: string[] = [];\n for (const resource of resources) {\n const key = typeof resource === 'string' ? resource : resource.value;\n const path = prefix ? `${prefix}.${key}` : key;\n paths.push(path);\n if (typeof resource !== 'string')\n paths.push(...getResourcePaths(resource.subResources, path));\n }\n return paths;\n}\n"],"mappings":";;AAGA,MAAa,sBAAsB,OAAO,oCAAoC;AAgB9E,SAAgB,sBACd,OAC6D;CAC7D,OACE,UAAU,QAAQ,OAAO,UAAU,YAAY,uBAAuB;AAE1E;AAEA,SAAgB,iBACd,WACA,SAAS,IACT;CACA,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,YAAY,WAAW;EAChC,MAAM,MAAM,OAAO,aAAa,WAAW,WAAW,SAAS;EAC/D,MAAM,OAAO,SAAS,GAAG,OAAO,GAAG,QAAQ;EAC3C,MAAM,KAAK,IAAI;EACf,IAAI,OAAO,aAAa,UACtB,MAAM,KAAK,GAAG,iBAAiB,SAAS,cAAc,IAAI,CAAC;CAC/D;CACA,OAAO;AACT"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ResourceDefinition } from "../resource.cjs";
|
|
2
|
+
import { LayoutResourcesAccessor } from "./define-layout.cjs";
|
|
3
|
+
|
|
4
|
+
//#region src/create-config/reusable-resource-input.d.ts
|
|
5
|
+
declare const singleResourceInput: unique symbol;
|
|
6
|
+
/** Describes one configured resource path supplied by the reusable's caller. */
|
|
7
|
+
type SingleResourceInput<Resources extends readonly ResourceDefinition[]> = {
|
|
8
|
+
readonly [singleResourceInput]: Resources;
|
|
9
|
+
};
|
|
10
|
+
/** Resource selector capabilities available to reusable definitions. */
|
|
11
|
+
type ReusableResourcesAccessor<Resources extends readonly ResourceDefinition[]> = LayoutResourcesAccessor<Resources> & {
|
|
12
|
+
single(): SingleResourceInput<Resources>;
|
|
13
|
+
};
|
|
14
|
+
//#endregion
|
|
15
|
+
export { ReusableResourcesAccessor, SingleResourceInput };
|
|
16
|
+
//# sourceMappingURL=reusable-resource-input.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reusable-resource-input.d.cts","names":[],"sources":["../../src/create-config/reusable-resource-input.ts"],"mappings":";;;;cAGa,mBAAA;;KAGD,mBAAA,4BACiB,kBAAA;EAAA,UAEjB,mBAAA,GAAsB,SAAA;AAAA;;KAItB,yBAAA,4BACiB,kBAAA,MACzB,uBAAA,CAAwB,SAAA;EAC1B,MAAA,IAAU,mBAAA,CAAoB,SAAA;AAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ResourceDefinition } from "../resource.mjs";
|
|
2
|
+
import { LayoutResourcesAccessor } from "./define-layout.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/create-config/reusable-resource-input.d.ts
|
|
5
|
+
declare const singleResourceInput: unique symbol;
|
|
6
|
+
/** Describes one configured resource path supplied by the reusable's caller. */
|
|
7
|
+
type SingleResourceInput<Resources extends readonly ResourceDefinition[]> = {
|
|
8
|
+
readonly [singleResourceInput]: Resources;
|
|
9
|
+
};
|
|
10
|
+
/** Resource selector capabilities available to reusable definitions. */
|
|
11
|
+
type ReusableResourcesAccessor<Resources extends readonly ResourceDefinition[]> = LayoutResourcesAccessor<Resources> & {
|
|
12
|
+
single(): SingleResourceInput<Resources>;
|
|
13
|
+
};
|
|
14
|
+
//#endregion
|
|
15
|
+
export { ReusableResourcesAccessor, SingleResourceInput };
|
|
16
|
+
//# sourceMappingURL=reusable-resource-input.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reusable-resource-input.d.mts","names":[],"sources":["../../src/create-config/reusable-resource-input.ts"],"mappings":";;;;cAGa,mBAAA;;KAGD,mBAAA,4BACiB,kBAAA;EAAA,UAEjB,mBAAA,GAAsB,SAAA;AAAA;;KAItB,yBAAA,4BACiB,kBAAA,MACzB,uBAAA,CAAwB,SAAA;EAC1B,MAAA,IAAU,mBAAA,CAAoB,SAAA;AAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/create-config/reusable-resource-input.ts
|
|
2
|
+
const singleResourceInput = Symbol("react-layout.single-resource-input");
|
|
3
|
+
function isSingleResourceInput(value) {
|
|
4
|
+
return value !== null && typeof value === "object" && singleResourceInput in value;
|
|
5
|
+
}
|
|
6
|
+
function getResourcePaths(resources, prefix = "") {
|
|
7
|
+
const paths = [];
|
|
8
|
+
for (const resource of resources) {
|
|
9
|
+
const key = typeof resource === "string" ? resource : resource.value;
|
|
10
|
+
const path = prefix ? `${prefix}.${key}` : key;
|
|
11
|
+
paths.push(path);
|
|
12
|
+
if (typeof resource !== "string") paths.push(...getResourcePaths(resource.subResources, path));
|
|
13
|
+
}
|
|
14
|
+
return paths;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { getResourcePaths, isSingleResourceInput, singleResourceInput };
|
|
19
|
+
//# sourceMappingURL=reusable-resource-input.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reusable-resource-input.mjs","names":[],"sources":["../../src/create-config/reusable-resource-input.ts"],"sourcesContent":["import type { LayoutResourcesAccessor } from './define-layout';\nimport type { ResourceDefinition } from '../resource';\n\nexport const singleResourceInput = Symbol('react-layout.single-resource-input');\n\n/** Describes one configured resource path supplied by the reusable's caller. */\nexport type SingleResourceInput<\n Resources extends readonly ResourceDefinition[],\n> = {\n readonly [singleResourceInput]: Resources;\n};\n\n/** Resource selector capabilities available to reusable definitions. */\nexport type ReusableResourcesAccessor<\n Resources extends readonly ResourceDefinition[],\n> = LayoutResourcesAccessor<Resources> & {\n single(): SingleResourceInput<Resources>;\n};\n\nexport function isSingleResourceInput(\n value: unknown,\n): value is SingleResourceInput<readonly ResourceDefinition[]> {\n return (\n value !== null && typeof value === 'object' && singleResourceInput in value\n );\n}\n\nexport function getResourcePaths(\n resources: readonly ResourceDefinition[],\n prefix = '',\n) {\n const paths: string[] = [];\n for (const resource of resources) {\n const key = typeof resource === 'string' ? resource : resource.value;\n const path = prefix ? `${prefix}.${key}` : key;\n paths.push(path);\n if (typeof resource !== 'string')\n paths.push(...getResourcePaths(resource.subResources, path));\n }\n return paths;\n}\n"],"mappings":";AAGA,MAAa,sBAAsB,OAAO,oCAAoC;AAgB9E,SAAgB,sBACd,OAC6D;CAC7D,OACE,UAAU,QAAQ,OAAO,UAAU,YAAY,uBAAuB;AAE1E;AAEA,SAAgB,iBACd,WACA,SAAS,IACT;CACA,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,YAAY,WAAW;EAChC,MAAM,MAAM,OAAO,aAAa,WAAW,WAAW,SAAS;EAC/D,MAAM,OAAO,SAAS,GAAG,OAAO,GAAG,QAAQ;EAC3C,MAAM,KAAK,IAAI;EACf,IAAI,OAAO,aAAa,UACtB,MAAM,KAAK,GAAG,iBAAiB,SAAS,cAAc,IAAI,CAAC;CAC/D;CACA,OAAO;AACT"}
|