Skip to content

Commit 0e20ac8

Browse files
committed
Enhanced interface FrameworkOptions by property getDerivedHostState
1 parent 9079959 commit 0e20ac8

File tree

6 files changed

+54
-12
lines changed

6 files changed

+54
-12
lines changed

CHANGES.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## Version 0.0.17 (in development)
2+
3+
* Enhanced interface `FrameworkOptions` by property `getDerivedHostState`,
4+
which is a user-supplied function that can compute derived
5+
host state property.
6+
7+
18
## Version 0.0.16 (from 2024/11/12)
29

310
Initial, still experimental version.

chartlets.js/src/lib/actions/handleComponentChange.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ function getCallbackRequests(
4949
changeEvent: ComponentChangeEvent,
5050
): CallbackRequest[] {
5151
const { configuration, contributionsRecord } = store.getState();
52-
const { hostStore } = configuration;
52+
const { hostStore, getDerivedHostState } = configuration;
5353
const hostState = hostStore?.getState();
5454
const contributions = contributionsRecord[contribPoint];
5555
const contribution = contributions[contribIndex];
@@ -71,7 +71,12 @@ function getCallbackRequests(
7171
contribIndex,
7272
callbackIndex,
7373
inputIndex,
74-
inputValues: getInputValues(inputs, contribution, hostState),
74+
inputValues: getInputValues(
75+
inputs,
76+
contribution,
77+
hostState,
78+
getDerivedHostState,
79+
),
7580
});
7681
}
7782
}

chartlets.js/src/lib/actions/helpers/getInputValues.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,19 @@ describe("Test that getInputValueFromState()", () => {
116116
getInputValueFromState({ link: "container", property: "x.y.2" }, state),
117117
).toEqual(6);
118118
});
119+
120+
it("works with derived state", () => {
121+
const state = { x: { y: [4, 5, 6] } };
122+
const getDerivedState = (_state: object, name: string): number | undefined =>
123+
name === "x.ySum"
124+
? state.x.y[0] + state.x.y[1] + state.x.y[2]
125+
: undefined;
126+
expect(
127+
getInputValueFromState(
128+
{ link: "container", property: "x.ySum" },
129+
state,
130+
getDerivedState,
131+
),
132+
).toEqual(4 + 5 + 6);
133+
});
119134
});

chartlets.js/src/lib/actions/helpers/getInputValues.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@ import type { Input } from "@/lib/types/model/channel";
22
import type { ContributionState } from "@/lib/types/state/contribution";
33
import type { ComponentState } from "@/lib/types/state/component";
44
import { isContainerState } from "@/lib/actions/helpers/isContainerState";
5-
import { getValue } from "@/lib/utils/objPath";
5+
import { getValue, toObjPath } from '@/lib/utils/objPath';
66
import { isObject } from "@/lib/utils/isObject";
77

88
export function getInputValues<S extends object = object>(
99
inputs: Input[],
1010
contributionState: ContributionState,
1111
hostState?: S | undefined,
12+
getDerivedHostState?: (hostState: object, property: string) => unknown,
1213
): unknown[] {
1314
return inputs.map((input) =>
14-
getInputValue(input, contributionState, hostState),
15+
getInputValue(input, contributionState, hostState, getDerivedHostState),
1516
);
1617
}
1718

@@ -20,7 +21,8 @@ const noValue = {};
2021
export function getInputValue<S extends object = object>(
2122
input: Input,
2223
contributionState: ContributionState,
23-
hostState?: S | undefined,
24+
hostState?: S,
25+
getDerivedHostState?: (hostState: object, propertyName: string) => unknown,
2426
): unknown {
2527
let inputValue: unknown = undefined;
2628
const dataSource = input.link || "component";
@@ -29,8 +31,7 @@ export function getInputValue<S extends object = object>(
2931
} else if (dataSource === "container" && contributionState.container) {
3032
inputValue = getInputValueFromState(input, contributionState.container);
3133
} else if (dataSource === "app" && hostState) {
32-
console.log();
33-
inputValue = getInputValueFromState(input, hostState);
34+
inputValue = getInputValueFromState(input, hostState, getDerivedHostState);
3435
} else {
3536
console.warn(`input with unknown data source:`, input);
3637
}
@@ -64,14 +65,21 @@ export function getInputValueFromComponent(
6465
// we export for testing only
6566
export function getInputValueFromState(
6667
input: Input,
67-
state: unknown,
68-
): unknown | undefined {
68+
state: object | undefined,
69+
getDerivedState?: (state: object, propertyName: string) => unknown,
70+
): unknown {
6971
let inputValue: unknown = state;
7072
if (input.id && isObject(inputValue)) {
7173
inputValue = inputValue[input.id];
7274
}
7375
if (isObject(inputValue)) {
74-
inputValue = getValue(inputValue, input.property);
76+
const state = inputValue;
77+
const property = toObjPath(input.property);
78+
inputValue = getValue(state, property);
79+
if (inputValue === undefined && getDerivedState !== undefined) {
80+
const propertyName = property.map(v => typeof v === "number" ? v.toString() : v).join(".");
81+
inputValue = getDerivedState(state, propertyName);
82+
}
7583
}
7684
return inputValue;
7785
}

chartlets.js/src/lib/actions/updateContributionContainer.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,17 @@ function getLayoutInputValues(
4848
contribIndex: number,
4949
): unknown[] {
5050
const { configuration, contributionsRecord } = store.getState();
51-
const { hostStore } = configuration;
51+
const { hostStore, getDerivedHostState } = configuration;
5252
const contributions = contributionsRecord[contribPoint];
5353
const contribution = contributions[contribIndex];
5454
const inputs = contribution.layout!.inputs;
5555
if (inputs && inputs.length > 0) {
56-
return getInputValues(inputs, contribution, hostStore?.getState());
56+
return getInputValues(
57+
inputs,
58+
contribution,
59+
hostStore?.getState(),
60+
getDerivedHostState,
61+
);
5762
} else {
5863
return [];
5964
}

chartlets.js/src/lib/types/state/store.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import type { LoggingOptions } from "@/lib/actions/helpers/configureLogging";
1212
export interface FrameworkOptions<S extends object = object> {
1313
/** The host applications state management store. */
1414
hostStore?: StoreApi<S>;
15+
/** Get a derived state from given host state. */
16+
getDerivedHostState?: <S>(hostState: S, propertyName: string) => unknown;
1517
/** API options to configure backend. */
1618
api?: ApiOptions;
1719
/** Logging options. */

0 commit comments

Comments
 (0)