diff --git a/packages/libs/designer-decisions/src/decisions/createStaticDecisionMap.ts b/packages/libs/designer-decisions/src/decisions/createStaticDecisionMap.ts index 07f6004..eb696bf 100644 --- a/packages/libs/designer-decisions/src/decisions/createStaticDecisionMap.ts +++ b/packages/libs/designer-decisions/src/decisions/createStaticDecisionMap.ts @@ -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, @@ -18,7 +24,7 @@ export const createStaticDecisionMap = (inputStore: StaticInputMap): StaticDecis } }; - const resolver = ( + const resolver = >( ref: DecisionRef, ): [DecisionContext, Decision | undefined] => { const inputs = inputStore.records(r => '$name' in ref && r.name === ref.$name); // WIP ref matching diff --git a/packages/libs/designer-decisions/src/decisions/createStaticStoreDecision.ts b/packages/libs/designer-decisions/src/decisions/createStaticStoreDecision.ts index e064361..b8d9e5b 100644 --- a/packages/libs/designer-decisions/src/decisions/createStaticStoreDecision.ts +++ b/packages/libs/designer-decisions/src/decisions/createStaticStoreDecision.ts @@ -1,4 +1,5 @@ import type { + BaseValue, Decision, DecisionContext, DecisionInputBase, @@ -9,20 +10,20 @@ import { createDecisionValueContext } from '../values'; import { getDecisionModelFactory } from '.'; -export const createStaticStoreDecision = ( +export const createStaticStoreDecision = ( decisionContext: DecisionContext, inputs: DecisionInputBase[], -): Decision => { - const produce = (context?: LookupContexts | ParentValueContext): V => { +): Decision> => { + const produce = (context?: LookupContexts | ParentValueContext): BaseValue => { const input = inputs[0]; // WIP match context - const modelFactory = getDecisionModelFactory(input.model); + const modelFactory = getDecisionModelFactory(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; }; - const api: Decision = { + const api: Decision> = { uuid: () => inputs[0].uuid, type: () => inputs[0].model.split('/')[0], name: () => inputs[0].name, diff --git a/packages/libs/designer-decisions/src/primitives/color/oklab-chroma-scale/createOklabChromaScale.ts b/packages/libs/designer-decisions/src/primitives/color/oklab-chroma-scale/createOklabChromaScale.ts index 704f3fb..e1605d5 100644 --- a/packages/libs/designer-decisions/src/primitives/color/oklab-chroma-scale/createOklabChromaScale.ts +++ b/packages/libs/designer-decisions/src/primitives/color/oklab-chroma-scale/createOklabChromaScale.ts @@ -1,4 +1,5 @@ import type { DecisionValueContext, OklabChromaScale, OklabChromaValue } from '../../../types'; +import { createItemSet } from '../../set'; export const createOklabChromaScale = ( context: DecisionValueContext, @@ -6,7 +7,9 @@ export const createOklabChromaScale = ( ): OklabChromaScale => { context.consume(input); + const items = createItemSet(input); + return { - get: () => input, + get: () => items, }; }; diff --git a/packages/libs/designer-decisions/src/primitives/color/oklab-hue-set/createOklabHueSet.ts b/packages/libs/designer-decisions/src/primitives/color/oklab-hue-set/createOklabHueSet.ts index d55d6fe..08fe6b1 100644 --- a/packages/libs/designer-decisions/src/primitives/color/oklab-hue-set/createOklabHueSet.ts +++ b/packages/libs/designer-decisions/src/primitives/color/oklab-hue-set/createOklabHueSet.ts @@ -1,4 +1,5 @@ import type { DecisionValueContext, OklabHueSet, OklabHueValue } from '../../../types'; +import { createItemSet } from '../../set'; export const createOklabHueSet = ( context: DecisionValueContext, @@ -6,7 +7,9 @@ export const createOklabHueSet = ( ): OklabHueSet => { context.consume(input); + const items = createItemSet(input); + return { - get: () => input, + get: () => items, }; }; diff --git a/packages/libs/designer-decisions/src/primitives/color/oklab-lightness-scale/createOklabLightnessScale.ts b/packages/libs/designer-decisions/src/primitives/color/oklab-lightness-scale/createOklabLightnessScale.ts index 9ef5023..6d86e07 100644 --- a/packages/libs/designer-decisions/src/primitives/color/oklab-lightness-scale/createOklabLightnessScale.ts +++ b/packages/libs/designer-decisions/src/primitives/color/oklab-lightness-scale/createOklabLightnessScale.ts @@ -3,6 +3,7 @@ import type { OklabLightnessScale, OklabLightnessValue, } from '../../../types'; +import { createItemSet } from '../../set'; export const createOklabLightnessScale = ( context: DecisionValueContext, @@ -10,7 +11,9 @@ export const createOklabLightnessScale = ( ): OklabLightnessScale => { context.consume(input); + const items = createItemSet(input); + return { - get: () => input, + get: () => items, }; }; diff --git a/packages/libs/designer-decisions/src/primitives/color/set/createColorSet.ts b/packages/libs/designer-decisions/src/primitives/color/set/createColorSet.ts index 062bb7a..9440c2d 100644 --- a/packages/libs/designer-decisions/src/primitives/color/set/createColorSet.ts +++ b/packages/libs/designer-decisions/src/primitives/color/set/createColorSet.ts @@ -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, }; }; diff --git a/packages/libs/designer-decisions/src/primitives/color/srgb-hue-set/createSRGBHueSet.ts b/packages/libs/designer-decisions/src/primitives/color/srgb-hue-set/createSRGBHueSet.ts index 3830699..b20b44b 100644 --- a/packages/libs/designer-decisions/src/primitives/color/srgb-hue-set/createSRGBHueSet.ts +++ b/packages/libs/designer-decisions/src/primitives/color/srgb-hue-set/createSRGBHueSet.ts @@ -1,4 +1,5 @@ import type { DecisionValueContext, SRGBHueSet, SRGBHueValue } from '../../../types'; +import { createItemSet } from '../../set'; export const createSRGBHueSet = ( context: DecisionValueContext, @@ -6,7 +7,9 @@ export const createSRGBHueSet = ( ): SRGBHueSet => { context.consume(input); + const items = createItemSet(input); + return { - get: () => input, + get: () => items, }; }; diff --git a/packages/libs/designer-decisions/src/primitives/color/srgb-lightness-scale/createSRGBLightnessScale.ts b/packages/libs/designer-decisions/src/primitives/color/srgb-lightness-scale/createSRGBLightnessScale.ts index d95e283..e9df599 100644 --- a/packages/libs/designer-decisions/src/primitives/color/srgb-lightness-scale/createSRGBLightnessScale.ts +++ b/packages/libs/designer-decisions/src/primitives/color/srgb-lightness-scale/createSRGBLightnessScale.ts @@ -1,4 +1,5 @@ import type { DecisionValueContext, SRGBLightnessScale, SRGBLightnessValue } from '../../../types'; +import { createItemSet } from '../../set'; export const createSRGBLightnessScale = ( context: DecisionValueContext, @@ -6,7 +7,9 @@ export const createSRGBLightnessScale = ( ): SRGBLightnessScale => { context.consume(input); + const items = createItemSet(input); + return { - get: () => input, + get: () => items, }; }; diff --git a/packages/libs/designer-decisions/src/primitives/color/srgb-saturation-scale/createSRGBSaturationScale.ts b/packages/libs/designer-decisions/src/primitives/color/srgb-saturation-scale/createSRGBSaturationScale.ts index 252dfe4..b2e04a7 100644 --- a/packages/libs/designer-decisions/src/primitives/color/srgb-saturation-scale/createSRGBSaturationScale.ts +++ b/packages/libs/designer-decisions/src/primitives/color/srgb-saturation-scale/createSRGBSaturationScale.ts @@ -3,6 +3,7 @@ import type { SRGBSaturationScale, SRGBSaturationValue, } from '../../../types'; +import { createItemSet } from '../../set'; export const createSRGBSaturationScale = ( context: DecisionValueContext, @@ -10,7 +11,9 @@ export const createSRGBSaturationScale = ( ): SRGBSaturationScale => { context.consume(input); + const items = createItemSet(input); + return { - get: () => input, + get: () => items, }; }; diff --git a/packages/libs/designer-decisions/src/primitives/color/value/resolveColorValueRef.ts b/packages/libs/designer-decisions/src/primitives/color/value/resolveColorValueRef.ts index 12bdaae..386f7bf 100644 --- a/packages/libs/designer-decisions/src/primitives/color/value/resolveColorValueRef.ts +++ b/packages/libs/designer-decisions/src/primitives/color/value/resolveColorValueRef.ts @@ -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); diff --git a/packages/libs/designer-decisions/src/primitives/set/createItemSet.ts b/packages/libs/designer-decisions/src/primitives/set/createItemSet.ts new file mode 100644 index 0000000..b3efd1d --- /dev/null +++ b/packages/libs/designer-decisions/src/primitives/set/createItemSet.ts @@ -0,0 +1,6 @@ +import type { SetItems } from '../../types'; + +export const createItemSet = (items: T[]): SetItems => ({ + items: () => items, + item: index => items[index], +}); diff --git a/packages/libs/designer-decisions/src/primitives/set/index.ts b/packages/libs/designer-decisions/src/primitives/set/index.ts new file mode 100644 index 0000000..ea11286 --- /dev/null +++ b/packages/libs/designer-decisions/src/primitives/set/index.ts @@ -0,0 +1,2 @@ +// @index(['./*.{ts,tsx}', './!(private|parts|functions)*/index.{ts,tsx}'], f => `export * from '${f.path.replace(/\/index$/, '')}';`) +export * from './createItemSet'; diff --git a/packages/libs/designer-decisions/src/primitives/space/scale/createSpaceScale.ts b/packages/libs/designer-decisions/src/primitives/space/scale/createSpaceScale.ts index 3b3811b..d02831d 100644 --- a/packages/libs/designer-decisions/src/primitives/space/scale/createSpaceScale.ts +++ b/packages/libs/designer-decisions/src/primitives/space/scale/createSpaceScale.ts @@ -1,4 +1,5 @@ import type { DecisionValueContext, SpaceScale, SpaceValue } from '../../../types'; +import { createItemSet } from '../../set'; export const createSpaceScale = ( context: DecisionValueContext, @@ -6,7 +7,9 @@ export const createSpaceScale = ( ): SpaceScale => { context.consume(input); + const items = createItemSet(input); + return { - get: () => input, + get: () => items, }; }; diff --git a/packages/libs/designer-decisions/src/primitives/space/value/resolveSpaceValueRef.ts b/packages/libs/designer-decisions/src/primitives/space/value/resolveSpaceValueRef.ts index 1ddc53d..bbc8f18 100644 --- a/packages/libs/designer-decisions/src/primitives/space/value/resolveSpaceValueRef.ts +++ b/packages/libs/designer-decisions/src/primitives/space/value/resolveSpaceValueRef.ts @@ -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); diff --git a/packages/libs/designer-decisions/src/types/decision-values/base.ts b/packages/libs/designer-decisions/src/types/decision-values/base.ts index d2bd5a0..5bb5f3d 100644 --- a/packages/libs/designer-decisions/src/types/decision-values/base.ts +++ b/packages/libs/designer-decisions/src/types/decision-values/base.ts @@ -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; @@ -22,7 +23,7 @@ export type DecisionContext = { export type DecisionLookup = { ref: DecisionRef; - decision: Decision; + decision: DecisionUnknown; }; export type DecisionValueError = { @@ -59,7 +60,7 @@ export type LookupContexts = { any?: string[]; }; -export type Decision = { +export type Decision> = { type: () => string; uuid: () => string | undefined; name: () => string; @@ -74,8 +75,8 @@ export type Decision = { export type DecisionFactory = ( input: unknown, - resolver: (ref: DecisionRef) => Decision, -) => Decision; + resolver: >(ref: DecisionRef) => Decision, +) => Decision>; export type DecisionNameRef = { $name: DecisionName; @@ -89,17 +90,17 @@ export type DecisionUuidRef = { export type DecisionRef = DecisionNameRef | DecisionUuidRef; -export type DecisionRefResolver = ( +export type DecisionRefResolver = = BaseValue>( ref: DecisionRef, ) => [DecisionContext, Decision | undefined]; -export type DecisionModel = { +export type DecisionModel, P = object> = { produce: (context: DecisionValueContext, params: P) => V; }; export type DecisionModelFactory< - V = unknown, + V = BaseValue, I extends DecisionInputBase = DecisionInputBase, > = () => DecisionModel; -export type DecisionUnknown = Decision; +export type DecisionUnknown = Decision>; diff --git a/packages/libs/designer-decisions/src/types/primitive-values/base.ts b/packages/libs/designer-decisions/src/types/primitive-values/base.ts index ee88575..5746c86 100644 --- a/packages/libs/designer-decisions/src/types/primitive-values/base.ts +++ b/packages/libs/designer-decisions/src/types/primitive-values/base.ts @@ -2,6 +2,9 @@ export type BaseValue = { get(): T; }; -export type BaseSet = { - get(): T[]; +export type SetItems = { + items(): T[]; + item(index: number): T | undefined; }; + +export type BaseSet = BaseValue>; diff --git a/packages/libs/designer-decisions/src/values/errors/createRefMatchError.ts b/packages/libs/designer-decisions/src/values/errors/createRefMatchError.ts index 09f3e55..b0e1bc4 100644 --- a/packages/libs/designer-decisions/src/values/errors/createRefMatchError.ts +++ b/packages/libs/designer-decisions/src/values/errors/createRefMatchError.ts @@ -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, + decision: DecisionUnknown, accepted: string[], ): DecisionValueError => { const refStr = JSON.stringify(ref); diff --git a/packages/libs/designer-decisions/src/values/functions/createValueContext.ts b/packages/libs/designer-decisions/src/values/functions/createValueContext.ts index 39b45be..4c9aae4 100644 --- a/packages/libs/designer-decisions/src/values/functions/createValueContext.ts +++ b/packages/libs/designer-decisions/src/values/functions/createValueContext.ts @@ -1,5 +1,6 @@ import { isLookupContext } from '../../context'; import type { + BaseValue, Decision, DecisionContext, DecisionInputBase, @@ -33,7 +34,9 @@ export const createValueContext = ( const lookups: DecisionLookup[] = []; const errors: DecisionValueError[] = []; - const resolve = (ref: DecisionRef): [DecisionContext, Decision | undefined] => { + const resolve = = BaseValue>( + ref: DecisionRef, + ): [DecisionContext, Decision | undefined] => { const [decisionContext, decision] = resolver(ref); lookups.push({ ref, diff --git a/packages/libs/designer-functions/src/cli/helpers/getDecisionStatus.ts b/packages/libs/designer-functions/src/cli/helpers/getDecisionStatus.ts index 26e2ed0..7a64d94 100644 --- a/packages/libs/designer-functions/src/cli/helpers/getDecisionStatus.ts +++ b/packages/libs/designer-functions/src/cli/helpers/getDecisionStatus.ts @@ -1,6 +1,6 @@ import { - type Decision, type DecisionInputBase, + type DecisionUnknown, createLookupContext, } from '@noodlestan/designer-decisions'; @@ -8,7 +8,7 @@ import type { StaticDecisionStore } from '../../store'; import type { DecisionStatus } from './types'; -const extractValue = (decision?: Decision) => { +const extractValue = (decision?: DecisionUnknown) => { const value = decision?.produce(); if ( typeof value === 'object' && diff --git a/packages/libs/designer-functions/src/store/createStaticDecisionStore.ts b/packages/libs/designer-functions/src/store/createStaticDecisionStore.ts index 854b2c4..3c97b84 100644 --- a/packages/libs/designer-functions/src/store/createStaticDecisionStore.ts +++ b/packages/libs/designer-functions/src/store/createStaticDecisionStore.ts @@ -1,4 +1,5 @@ import type { + BaseValue, Decision, DecisionContext, DecisionInputBase, @@ -26,7 +27,7 @@ export const createStaticDecisionStore = ( ): StaticDecisionStore => { const decisionMap = createStaticDecisionMap(inputStore); - const decision = ( + const decision = = BaseValue>( ref: DecisionRef, ): [DecisionContext, Decision | undefined] => { return decisionMap.resolve(ref); diff --git a/packages/libs/designer-functions/src/store/types.ts b/packages/libs/designer-functions/src/store/types.ts index 82ad4b4..8ed6c25 100644 --- a/packages/libs/designer-functions/src/store/types.ts +++ b/packages/libs/designer-functions/src/store/types.ts @@ -1,4 +1,5 @@ import type { + BaseValue, Decision, DecisionContext, DecisionRef, @@ -18,7 +19,7 @@ export type StaticDecisionStore = { storeErrors: () => StaticDecisionStoreError[]; validationErrors: StaticInputMap['validationErrors']; records: StaticInputMap['records']; - decision: ( + decision: = BaseValue>( ref: DecisionRef, contexts?: LookupContexts, ) => [DecisionContext, Decision | undefined]; diff --git a/packages/libs/designer-shows/src/astro/decisions/color/ShowColorSRGBHueSetDecision.astro b/packages/libs/designer-shows/src/astro/decisions/color/ShowColorSRGBHueSetDecision.astro index 5b5c4a0..5eed802 100644 --- a/packages/libs/designer-shows/src/astro/decisions/color/ShowColorSRGBHueSetDecision.astro +++ b/packages/libs/designer-shows/src/astro/decisions/color/ShowColorSRGBHueSetDecision.astro @@ -13,7 +13,7 @@ const { store, d, size, ...rest } = Astro.props; const [, decision] = store.decision({ $name: d }); const hueSet = decision && isColorSRGBHueSetDecision(decision) ? decision.produce() : undefined; -const items = hueSet?.get(); +const items = hueSet?.get().items(); const s = size || 's'; --- diff --git a/packages/libs/designer-shows/src/astro/decisions/color/ShowColorSRGBLightnessScaleDecision.astro b/packages/libs/designer-shows/src/astro/decisions/color/ShowColorSRGBLightnessScaleDecision.astro index d015ed7..21a3fde 100644 --- a/packages/libs/designer-shows/src/astro/decisions/color/ShowColorSRGBLightnessScaleDecision.astro +++ b/packages/libs/designer-shows/src/astro/decisions/color/ShowColorSRGBLightnessScaleDecision.astro @@ -14,7 +14,7 @@ const [, decision] = store.decision({ $name: d }); const lightnessScale = decision && isColorSRGBLightnessScaleDecision(decision) ? decision.produce() : undefined; -const items = lightnessScale?.get(); +const items = lightnessScale?.get().items(); const s = size || 's'; --- diff --git a/packages/libs/designer-shows/src/astro/decisions/color/ShowColorSRGBSaturationScaleDecision.astro b/packages/libs/designer-shows/src/astro/decisions/color/ShowColorSRGBSaturationScaleDecision.astro index ab4d331..d0fcfc9 100644 --- a/packages/libs/designer-shows/src/astro/decisions/color/ShowColorSRGBSaturationScaleDecision.astro +++ b/packages/libs/designer-shows/src/astro/decisions/color/ShowColorSRGBSaturationScaleDecision.astro @@ -14,7 +14,7 @@ const [, decision] = store.decision({ $name: d }); const saturationScale = decision && isColorSRGBSaturationScaleDecision(decision) ? decision.produce() : undefined; -const items = saturationScale?.get(); +const items = saturationScale?.get().items(); const s = size || 's'; --- diff --git a/packages/libs/designer-shows/src/astro/decisions/color/ShowColorSetDecision.astro b/packages/libs/designer-shows/src/astro/decisions/color/ShowColorSetDecision.astro index 6d04b58..ec00e24 100644 --- a/packages/libs/designer-shows/src/astro/decisions/color/ShowColorSetDecision.astro +++ b/packages/libs/designer-shows/src/astro/decisions/color/ShowColorSetDecision.astro @@ -14,7 +14,7 @@ const { store, d, size, ...rest } = Astro.props; const [, decision] = store.decision({ $name: d }); const set = decision && isColorSetDecision(decision) ? decision.produce() : undefined; -const colors = set?.get(); +const colors = set?.get().items(); const s = size || 's'; --- diff --git a/packages/libs/designer-shows/src/astro/decisions/space/ShowSpaceScaleDecision.astro b/packages/libs/designer-shows/src/astro/decisions/space/ShowSpaceScaleDecision.astro index 2b5f7fb..de80009 100644 --- a/packages/libs/designer-shows/src/astro/decisions/space/ShowSpaceScaleDecision.astro +++ b/packages/libs/designer-shows/src/astro/decisions/space/ShowSpaceScaleDecision.astro @@ -13,7 +13,7 @@ const { store, d, size, ...rest } = Astro.props; const [, decision] = store.decision({ $name: d }); const spaceScale = decision && isSpaceScaleDecision(decision) ? decision.produce() : undefined; -const items = spaceScale?.get(); +const items = spaceScale?.get().items(); const s = size || 's'; --- diff --git a/packages/libs/designer-shows/src/astro/meta/getDecisionComponent.ts b/packages/libs/designer-shows/src/astro/meta/getDecisionComponent.ts index 0fbbd89..a272a08 100644 --- a/packages/libs/designer-shows/src/astro/meta/getDecisionComponent.ts +++ b/packages/libs/designer-shows/src/astro/meta/getDecisionComponent.ts @@ -1,4 +1,4 @@ -import { type Decision } from '@noodlestan/designer-decisions'; +import { type DecisionUnknown } from '@noodlestan/designer-decisions'; import { ShowColorSRGBHueSetDecision, @@ -15,7 +15,7 @@ import { import type { DecisionTypeComponent } from '../types'; export const getDecisionComponent = ( - decision: Decision, + decision: DecisionUnknown, ): DecisionTypeComponent | undefined => { // WIP we would rather have this in a constants.ts file but it looks like // component function references are not available in the unit scope