Skip to content

Commit

Permalink
Make sets and scales first class values (#65)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrezero authored Jan 24, 2025
1 parent d629119 commit f599006
Show file tree
Hide file tree
Showing 27 changed files with 119 additions and 42 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import type { StaticDecisionMap, StaticInputMap } from '../inputs';
import type { Decision, DecisionContext, DecisionInputBase, DecisionRef } from '../types';
import type {
BaseValue,
Decision,
DecisionContext,
DecisionInputBase,
DecisionRef,
} from '../types';

import {
createDecisionContext,
Expand All @@ -18,7 +24,7 @@ export const createStaticDecisionMap = (inputStore: StaticInputMap): StaticDecis
}
};

const resolver = <V = unknown>(
const resolver = <V extends BaseValue<unknown>>(
ref: DecisionRef,
): [DecisionContext, Decision<V> | undefined] => {
const inputs = inputStore.records(r => '$name' in ref && r.name === ref.$name); // WIP ref matching
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type {
BaseValue,
Decision,
DecisionContext,
DecisionInputBase,
Expand All @@ -9,20 +10,20 @@ import { createDecisionValueContext } from '../values';

import { getDecisionModelFactory } from '.';

export const createStaticStoreDecision = <V = unknown>(
export const createStaticStoreDecision = <T = unknown>(
decisionContext: DecisionContext,
inputs: DecisionInputBase[],
): Decision<V> => {
const produce = (context?: LookupContexts | ParentValueContext): V => {
): Decision<BaseValue<T>> => {
const produce = (context?: LookupContexts | ParentValueContext): BaseValue<T> => {
const input = inputs[0]; // WIP match context
const modelFactory = getDecisionModelFactory<V>(input.model);
const modelFactory = getDecisionModelFactory<T>(input.model);
const model = modelFactory();

const valueContext = createDecisionValueContext(decisionContext, context, input);
return model.produce(valueContext, input.params);
return model.produce(valueContext, input.params) as BaseValue<T>;
};

const api: Decision<V> = {
const api: Decision<BaseValue<T>> = {
uuid: () => inputs[0].uuid,
type: () => inputs[0].model.split('/')[0],
name: () => inputs[0].name,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import type { DecisionValueContext, OklabChromaScale, OklabChromaValue } from '../../../types';
import { createItemSet } from '../../set';

export const createOklabChromaScale = (
context: DecisionValueContext,
input: OklabChromaValue[],
): OklabChromaScale => {
context.consume(input);

const items = createItemSet(input);

return {
get: () => input,
get: () => items,
};
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import type { DecisionValueContext, OklabHueSet, OklabHueValue } from '../../../types';
import { createItemSet } from '../../set';

export const createOklabHueSet = (
context: DecisionValueContext,
input: OklabHueValue[],
): OklabHueSet => {
context.consume(input);

const items = createItemSet(input);

return {
get: () => input,
get: () => items,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ import type {
OklabLightnessScale,
OklabLightnessValue,
} from '../../../types';
import { createItemSet } from '../../set';

export const createOklabLightnessScale = (
context: DecisionValueContext,
input: OklabLightnessValue[],
): OklabLightnessScale => {
context.consume(input);

const items = createItemSet(input);

return {
get: () => input,
get: () => items,
};
};
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import type { ColorSet, ColorValue, DecisionValueContext } from '../../../types';
import { createItemSet } from '../../set';

export const createColorSet = (context: DecisionValueContext, input: ColorValue[]): ColorSet => {
context.consume(input);

const items = createItemSet(input);

return {
get: () => input,
get: () => items,
};
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import type { DecisionValueContext, SRGBHueSet, SRGBHueValue } from '../../../types';
import { createItemSet } from '../../set';

export const createSRGBHueSet = (
context: DecisionValueContext,
input: SRGBHueValue[],
): SRGBHueSet => {
context.consume(input);

const items = createItemSet(input);

return {
get: () => input,
get: () => items,
};
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import type { DecisionValueContext, SRGBLightnessScale, SRGBLightnessValue } from '../../../types';
import { createItemSet } from '../../set';

export const createSRGBLightnessScale = (
context: DecisionValueContext,
input: SRGBLightnessValue[],
): SRGBLightnessScale => {
context.consume(input);

const items = createItemSet(input);

return {
get: () => input,
get: () => items,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ import type {
SRGBSaturationScale,
SRGBSaturationValue,
} from '../../../types';
import { createItemSet } from '../../set';

export const createSRGBSaturationScale = (
context: DecisionValueContext,
input: SRGBSaturationValue[],
): SRGBSaturationScale => {
context.consume(input);

const items = createItemSet(input);

return {
get: () => input,
get: () => items,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,19 @@ export const resolveColorValueRef = (context: DecisionValueContext, ref: Decisio
return v.get();
} else if (isColorSetDecision(decision)) {
const set = decision.produce(context);
const v = set.get()[ref.index || 0];
const v = set.get().item(ref.index || 0);
if (!v) {
// WIP createRefIndexError
const error = createRefMatchError(
context,
VALUE_NAME,
ref,
decision,
REF_CHECKED_TYPES,
);
context.addError(error);
return FALLBACK_VALUE;
}
return v.get();
} else {
const error = createRefMatchError(context, VALUE_NAME, ref, decision, REF_CHECKED_TYPES);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type { SetItems } from '../../types';

export const createItemSet = <T>(items: T[]): SetItems<T> => ({
items: () => items,
item: index => items[index],
});
2 changes: 2 additions & 0 deletions packages/libs/designer-decisions/src/primitives/set/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// @index(['./*.{ts,tsx}', './!(private|parts|functions)*/index.{ts,tsx}'], f => `export * from '${f.path.replace(/\/index$/, '')}';`)
export * from './createItemSet';
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import type { DecisionValueContext, SpaceScale, SpaceValue } from '../../../types';
import { createItemSet } from '../../set';

export const createSpaceScale = (
context: DecisionValueContext,
input: SpaceValue[],
): SpaceScale => {
context.consume(input);

const items = createItemSet(input);

return {
get: () => input,
get: () => items,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,19 @@ export const resolveSpaceValueRef = (
return v.getValueWithUnits();
} else if (isSpaceScaleDecision(decision)) {
const scale = decision.produce(context);
const v = scale.get()[ref.index || 0];
const v = scale.get().item(ref.index || 0);
if (!v) {
// WIP createRefIndexError
const error = createRefMatchError(
context,
VALUE_NAME,
ref,
decision,
REF_CHECKED_TYPES,
);
context.addError(error);
return FALLBACK_VALUE;
}
return v.getValueWithUnits();
} else {
const error = createRefMatchError(context, VALUE_NAME, ref, decision, REF_CHECKED_TYPES);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { DecisionId, DecisionInputBase, DecisionName } from '../decision-inputs';
import type { BaseValue } from '../primitive-values';

export type Value = unknown;
export type Params = object;
Expand All @@ -22,7 +23,7 @@ export type DecisionContext = {

export type DecisionLookup = {
ref: DecisionRef;
decision: Decision<unknown>;
decision: DecisionUnknown;
};

export type DecisionValueError = {
Expand Down Expand Up @@ -59,7 +60,7 @@ export type LookupContexts = {
any?: string[];
};

export type Decision<V extends Value> = {
export type Decision<V extends BaseValue<unknown>> = {
type: () => string;
uuid: () => string | undefined;
name: () => string;
Expand All @@ -74,8 +75,8 @@ export type Decision<V extends Value> = {

export type DecisionFactory = <V = unknown>(
input: unknown,
resolver: <V>(ref: DecisionRef) => Decision<V>,
) => Decision<V>;
resolver: <V extends BaseValue<unknown>>(ref: DecisionRef) => Decision<V>,
) => Decision<BaseValue<V>>;

export type DecisionNameRef = {
$name: DecisionName;
Expand All @@ -89,17 +90,17 @@ export type DecisionUuidRef = {

export type DecisionRef = DecisionNameRef | DecisionUuidRef;

export type DecisionRefResolver = <V = unknown>(
export type DecisionRefResolver = <V extends BaseValue<unknown> = BaseValue<unknown>>(
ref: DecisionRef,
) => [DecisionContext, Decision<V> | undefined];

export type DecisionModel<V = unknown, P = object> = {
export type DecisionModel<V = BaseValue<unknown>, P = object> = {
produce: (context: DecisionValueContext, params: P) => V;
};

export type DecisionModelFactory<
V = unknown,
V = BaseValue<unknown>,
I extends DecisionInputBase = DecisionInputBase,
> = () => DecisionModel<V, I['params']>;

export type DecisionUnknown = Decision<unknown>;
export type DecisionUnknown = Decision<BaseValue<unknown>>;
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ export type BaseValue<T> = {
get(): T;
};

export type BaseSet<T> = {
get(): T[];
export type SetItems<T> = {
items(): T[];
item(index: number): T | undefined;
};

export type BaseSet<T> = BaseValue<SetItems<T>>;
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import type { Decision, DecisionRef, DecisionValueContext, DecisionValueError } from '../../types';
import type {
DecisionRef,
DecisionUnknown,
DecisionValueContext,
DecisionValueError,
} from '../../types';

export const createRefMatchError = (
context: DecisionValueContext,
valueName: string,
ref: DecisionRef,
decision: Decision<unknown>,
decision: DecisionUnknown,
accepted: string[],
): DecisionValueError => {
const refStr = JSON.stringify(ref);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { isLookupContext } from '../../context';
import type {
BaseValue,
Decision,
DecisionContext,
DecisionInputBase,
Expand Down Expand Up @@ -33,7 +34,9 @@ export const createValueContext = (
const lookups: DecisionLookup[] = [];
const errors: DecisionValueError[] = [];

const resolve = <V>(ref: DecisionRef): [DecisionContext, Decision<V> | undefined] => {
const resolve = <V extends BaseValue<unknown> = BaseValue<unknown>>(
ref: DecisionRef,
): [DecisionContext, Decision<V> | undefined] => {
const [decisionContext, decision] = resolver<V>(ref);
lookups.push({
ref,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {
type Decision,
type DecisionInputBase,
type DecisionUnknown,
createLookupContext,
} from '@noodlestan/designer-decisions';

import type { StaticDecisionStore } from '../../store';

import type { DecisionStatus } from './types';

const extractValue = (decision?: Decision<unknown>) => {
const extractValue = (decision?: DecisionUnknown) => {
const value = decision?.produce();
if (
typeof value === 'object' &&
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type {
BaseValue,
Decision,
DecisionContext,
DecisionInputBase,
Expand Down Expand Up @@ -26,7 +27,7 @@ export const createStaticDecisionStore = (
): StaticDecisionStore => {
const decisionMap = createStaticDecisionMap(inputStore);

const decision = <V = unknown>(
const decision = <V extends BaseValue<unknown> = BaseValue<unknown>>(
ref: DecisionRef,
): [DecisionContext, Decision<V> | undefined] => {
return decisionMap.resolve(ref);
Expand Down
3 changes: 2 additions & 1 deletion packages/libs/designer-functions/src/store/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type {
BaseValue,
Decision,
DecisionContext,
DecisionRef,
Expand All @@ -18,7 +19,7 @@ export type StaticDecisionStore = {
storeErrors: () => StaticDecisionStoreError[];
validationErrors: StaticInputMap['validationErrors'];
records: StaticInputMap['records'];
decision: <V = unknown>(
decision: <V extends BaseValue<unknown> = BaseValue<unknown>>(
ref: DecisionRef,
contexts?: LookupContexts,
) => [DecisionContext, Decision<V> | undefined];
Expand Down
Loading

0 comments on commit f599006

Please sign in to comment.