Skip to content

Commit 05f0940

Browse files
authoredJun 18, 2024··
feat(signals): rename signals to computed when defining custom features with input (#4395)
Closes #4391
1 parent 6ae4723 commit 05f0940

14 files changed

+115
-99
lines changed
 

Diff for: ‎modules/signals/entities/src/models.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ export type NamedEntityState<Entity, Collection extends string> = {
1313
[K in keyof EntityState<Entity> as `${Collection}${Capitalize<K>}`]: EntityState<Entity>[K];
1414
};
1515

16-
export type EntitySignals<Entity> = {
16+
export type EntityComputed<Entity> = {
1717
entities: Signal<Entity[]>;
1818
};
1919

20-
export type NamedEntitySignals<Entity, Collection extends string> = {
21-
[K in keyof EntitySignals<Entity> as `${Collection}${Capitalize<K>}`]: EntitySignals<Entity>[K];
20+
export type NamedEntityComputed<Entity, Collection extends string> = {
21+
[K in keyof EntityComputed<Entity> as `${Collection}${Capitalize<K>}`]: EntityComputed<Entity>[K];
2222
};
2323

2424
export type EntityIdProps<Entity> = {

Diff for: ‎modules/signals/entities/src/with-entities.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -6,41 +6,41 @@ import {
66
withState,
77
} from '@ngrx/signals';
88
import {
9+
EntityComputed,
910
EntityId,
1011
EntityMap,
11-
EntitySignals,
1212
EntityState,
13-
NamedEntitySignals,
13+
NamedEntityComputed,
1414
NamedEntityState,
1515
} from './models';
1616
import { getEntityStateKeys } from './helpers';
1717

1818
export function withEntities<Entity>(): SignalStoreFeature<
19-
{ state: {}; signals: {}; methods: {} },
19+
{ state: {}; computed: {}; methods: {} },
2020
{
2121
state: EntityState<Entity>;
22-
signals: EntitySignals<Entity>;
22+
computed: EntityComputed<Entity>;
2323
methods: {};
2424
}
2525
>;
2626
export function withEntities<Entity, Collection extends string>(config: {
2727
entity: Entity;
2828
collection: Collection;
2929
}): SignalStoreFeature<
30-
{ state: {}; signals: {}; methods: {} },
30+
{ state: {}; computed: {}; methods: {} },
3131
{
3232
state: NamedEntityState<Entity, Collection>;
33-
signals: NamedEntitySignals<Entity, Collection>;
33+
computed: NamedEntityComputed<Entity, Collection>;
3434
methods: {};
3535
}
3636
>;
3737
export function withEntities<Entity>(config: {
3838
entity: Entity;
3939
}): SignalStoreFeature<
40-
{ state: {}; signals: {}; methods: {} },
40+
{ state: {}; computed: {}; methods: {} },
4141
{
4242
state: EntityState<Entity>;
43-
signals: EntitySignals<Entity>;
43+
computed: EntityComputed<Entity>;
4444
methods: {};
4545
}
4646
>;

Diff for: ‎modules/signals/spec/signal-store-feature.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ describe('signalStoreFeature', () => {
3434
return signalStoreFeature(
3535
{
3636
state: type<{ foo: string }>(),
37-
signals: type<{ s: Signal<number> }>(),
37+
computed: type<{ s: Signal<number> }>(),
3838
},
3939
withState({ foo1: 1 }),
4040
withState({ foo2: 2 })

Diff for: ‎modules/signals/spec/types/signal-store.types.spec.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,7 @@ describe('signalStore', () => {
653653
return signalStoreFeature(
654654
{
655655
state: type<{ q1: string }>(),
656-
signals: type<{ sig: Signal<boolean> }>(),
656+
computed: type<{ sig: Signal<boolean> }>(),
657657
},
658658
withState({ y: initialY }),
659659
withComputed(() => ({ sigY: computed(() => 'sigY') })),
@@ -739,7 +739,7 @@ describe('signalStore', () => {
739739
);
740740
741741
const feature = signalStoreFeature(
742-
{ signals: type<{ sig: Signal<boolean> }>() },
742+
{ computed: type<{ sig: Signal<boolean> }>() },
743743
withX(),
744744
withState({ q1: 'q1' }),
745745
withY(),
@@ -785,7 +785,7 @@ describe('signalStore', () => {
785785
${baseSnippet}
786786
787787
const feature = signalStoreFeature(
788-
{ signals: type<{ sig: Signal<boolean> }>() },
788+
{ computed: type<{ sig: Signal<boolean> }>() },
789789
withComputed(() => ({ sig: computed(() => 1) })),
790790
withX(),
791791
withState({ q1: 'q1' }),
@@ -817,7 +817,7 @@ describe('signalStore', () => {
817817
);
818818
819819
const feature = signalStoreFeature(
820-
{ signals: type<{ sig: Signal<boolean> }>() },
820+
{ computed: type<{ sig: Signal<boolean> }>() },
821821
withComputed(() => ({ sig: computed(() => 1) })),
822822
withX(),
823823
withState({ q1: 'q1' }),
@@ -860,7 +860,7 @@ describe('signalStore', () => {
860860
entities: Entity[];
861861
selectedEntity: Entity | null;
862862
};
863-
signals: {
863+
computed: {
864864
selectedEntity2: Signal<Entity | undefined>;
865865
};
866866
methods: {

Diff for: ‎modules/signals/spec/with-computed.spec.ts

+15-9
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,22 @@ import { withComputed, withMethods, withState } from '../src';
33
import { getInitialInnerStore } from '../src/signal-store';
44

55
describe('withComputed', () => {
6-
it('adds signals to the store immutably', () => {
6+
it('adds computed signals to the store immutably', () => {
77
const initialStore = getInitialInnerStore();
88

99
const s1 = signal('s1').asReadonly();
1010
const s2 = signal(10).asReadonly();
1111

1212
const store = withComputed(() => ({ s1, s2 }))(initialStore);
1313

14-
expect(Object.keys(store.signals)).toEqual(['s1', 's2']);
15-
expect(Object.keys(initialStore.signals)).toEqual([]);
14+
expect(Object.keys(store.computedSignals)).toEqual(['s1', 's2']);
15+
expect(Object.keys(initialStore.computedSignals)).toEqual([]);
1616

17-
expect(store.signals.s1).toBe(s1);
18-
expect(store.signals.s2).toBe(s2);
17+
expect(store.computedSignals.s1).toBe(s1);
18+
expect(store.computedSignals.s2).toBe(s2);
1919
});
2020

21-
it('overrides previously defined slices, signals, and methods with the same name', () => {
21+
it('overrides previously defined state signals, computed signals, and methods with the same name', () => {
2222
const initialStore = [
2323
withState({
2424
p1: 10,
@@ -42,10 +42,16 @@ describe('withComputed', () => {
4242
s3: signal({ s: 3 }).asReadonly(),
4343
}))(initialStore);
4444

45-
expect(Object.keys(store.signals)).toEqual(['s1', 's2', 'p1', 'm1', 's3']);
46-
expect(store.signals.s2).toBe(s2);
45+
expect(Object.keys(store.computedSignals)).toEqual([
46+
's1',
47+
's2',
48+
'p1',
49+
'm1',
50+
's3',
51+
]);
52+
expect(store.computedSignals.s2).toBe(s2);
4753

48-
expect(Object.keys(store.slices)).toEqual(['p2']);
54+
expect(Object.keys(store.stateSignals)).toEqual(['p2']);
4955
expect(Object.keys(store.methods)).toEqual(['m2']);
5056
});
5157
});

Diff for: ‎modules/signals/spec/with-methods.spec.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ describe('withMethods', () => {
1818
expect(store.methods.m2).toBe(m2);
1919
});
2020

21-
it('overrides previously defined slices, signals, and methods with the same name', () => {
21+
it('overrides previously defined state signals, computed signals, and methods with the same name', () => {
2222
const initialStore = [
2323
withState({
2424
p1: 'p1',
@@ -45,7 +45,7 @@ describe('withMethods', () => {
4545
expect(Object.keys(store.methods)).toEqual(['m1', 'm2', 'p2', 's1', 'm3']);
4646
expect(store.methods.m2).toBe(m2);
4747

48-
expect(Object.keys(store.slices)).toEqual(['p1']);
49-
expect(Object.keys(store.signals)).toEqual(['s2']);
48+
expect(Object.keys(store.stateSignals)).toEqual(['p1']);
49+
expect(Object.keys(store.computedSignals)).toEqual(['s2']);
5050
});
5151
});

Diff for: ‎modules/signals/spec/with-state.spec.ts

+21-15
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ describe('withState', () => {
1717
expect(state).toEqual({ foo: 'bar', x: { y: 'z' } });
1818
expect(initialState).toEqual({});
1919

20-
expect(Object.keys(store.slices)).toEqual(['foo', 'x']);
21-
expect(Object.keys(initialStore.slices)).toEqual([]);
20+
expect(Object.keys(store.stateSignals)).toEqual(['foo', 'x']);
21+
expect(Object.keys(initialStore.stateSignals)).toEqual([]);
2222
});
2323

2424
it('creates deep signals for each state slice', () => {
@@ -29,14 +29,14 @@ describe('withState', () => {
2929
x: { y: 'z' },
3030
})(initialStore);
3131

32-
expect(store.slices.foo()).toBe('bar');
33-
expect(isSignal(store.slices.foo)).toBe(true);
32+
expect(store.stateSignals.foo()).toBe('bar');
33+
expect(isSignal(store.stateSignals.foo)).toBe(true);
3434

35-
expect(store.slices.x()).toEqual({ y: 'z' });
36-
expect(isSignal(store.slices.x)).toBe(true);
35+
expect(store.stateSignals.x()).toEqual({ y: 'z' });
36+
expect(isSignal(store.stateSignals.x)).toBe(true);
3737

38-
expect(store.slices.x.y()).toBe('z');
39-
expect(isSignal(store.slices.x.y)).toBe(true);
38+
expect(store.stateSignals.x.y()).toBe('z');
39+
expect(isSignal(store.stateSignals.x.y)).toBe(true);
4040
});
4141

4242
it('patches state signal and creates deep signals for state slices provided via factory', () => {
@@ -49,12 +49,12 @@ describe('withState', () => {
4949
const state = store[STATE_SIGNAL]();
5050

5151
expect(state).toEqual({ foo: 'bar', x: { y: 'z' } });
52-
expect(store.slices.foo()).toBe('bar');
53-
expect(store.slices.x()).toEqual({ y: 'z' });
54-
expect(store.slices.x.y()).toBe('z');
52+
expect(store.stateSignals.foo()).toBe('bar');
53+
expect(store.stateSignals.x()).toEqual({ y: 'z' });
54+
expect(store.stateSignals.x.y()).toBe('z');
5555
});
5656

57-
it('overrides previously defined state slices, signals, and methods with the same name', () => {
57+
it('overrides previously defined state signals, computed signals, and methods with the same name', () => {
5858
const initialStore = [
5959
withState({
6060
p1: 10,
@@ -77,10 +77,16 @@ describe('withState', () => {
7777
p3: 'p3',
7878
}))(initialStore);
7979

80-
expect(Object.keys(store.slices)).toEqual(['p1', 'p2', 's2', 'm2', 'p3']);
81-
expect(store.slices.p2()).toBe(100);
80+
expect(Object.keys(store.stateSignals)).toEqual([
81+
'p1',
82+
'p2',
83+
's2',
84+
'm2',
85+
'p3',
86+
]);
87+
expect(store.stateSignals.p2()).toBe(100);
8288

83-
expect(Object.keys(store.signals)).toEqual(['s1']);
89+
expect(Object.keys(store.computedSignals)).toEqual(['s1']);
8490
expect(Object.keys(store.methods)).toEqual(['m1']);
8591
});
8692
});

Diff for: ‎modules/signals/src/signal-store-models.ts

+12-14
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ import { IsKnownRecord, Prettify } from './ts-helpers';
55

66
export type SignalStoreConfig = { providedIn: 'root' };
77

8-
export type SignalStoreSlices<State> = IsKnownRecord<
9-
Prettify<State>
10-
> extends true
8+
export type StateSignals<State> = IsKnownRecord<Prettify<State>> extends true
119
? {
1210
[Key in keyof State]: IsKnownRecord<State[Key]> extends true
1311
? DeepSignal<State[Key]>
@@ -17,8 +15,8 @@ export type SignalStoreSlices<State> = IsKnownRecord<
1715

1816
export type SignalStoreProps<FeatureResult extends SignalStoreFeatureResult> =
1917
Prettify<
20-
SignalStoreSlices<FeatureResult['state']> &
21-
FeatureResult['signals'] &
18+
StateSignals<FeatureResult['state']> &
19+
FeatureResult['computed'] &
2220
FeatureResult['methods']
2321
>;
2422

@@ -33,29 +31,29 @@ export type SignalStoreHooks = {
3331

3432
export type InnerSignalStore<
3533
State extends object = object,
36-
Signals extends SignalsDictionary = SignalsDictionary,
34+
ComputedSignals extends SignalsDictionary = SignalsDictionary,
3735
Methods extends MethodsDictionary = MethodsDictionary
3836
> = {
39-
slices: SignalStoreSlices<State>;
40-
signals: Signals;
37+
stateSignals: StateSignals<State>;
38+
computedSignals: ComputedSignals;
4139
methods: Methods;
4240
hooks: SignalStoreHooks;
4341
} & StateSignal<State>;
4442

4543
export type SignalStoreFeatureResult = {
4644
state: object;
47-
signals: SignalsDictionary;
45+
computed: SignalsDictionary;
4846
methods: MethodsDictionary;
4947
};
5048

51-
export type EmptyFeatureResult = { state: {}; signals: {}; methods: {} };
49+
export type EmptyFeatureResult = { state: {}; computed: {}; methods: {} };
5250

5351
export type SignalStoreFeature<
5452
Input extends SignalStoreFeatureResult = SignalStoreFeatureResult,
5553
Output extends SignalStoreFeatureResult = SignalStoreFeatureResult
5654
> = (
57-
store: InnerSignalStore<Input['state'], Input['signals'], Input['methods']>
58-
) => InnerSignalStore<Output['state'], Output['signals'], Output['methods']>;
55+
store: InnerSignalStore<Input['state'], Input['computed'], Input['methods']>
56+
) => InnerSignalStore<Output['state'], Output['computed'], Output['methods']>;
5957

6058
export type MergeFeatureResults<
6159
FeatureResults extends SignalStoreFeatureResult[]
@@ -78,14 +76,14 @@ export type MergeFeatureResults<
7876

7977
type FeatureResultKeys<FeatureResult extends SignalStoreFeatureResult> =
8078
| keyof FeatureResult['state']
81-
| keyof FeatureResult['signals']
79+
| keyof FeatureResult['computed']
8280
| keyof FeatureResult['methods'];
8381

8482
type MergeTwoFeatureResults<
8583
First extends SignalStoreFeatureResult,
8684
Second extends SignalStoreFeatureResult
8785
> = {
8886
state: Omit<First['state'], FeatureResultKeys<Second>>;
89-
signals: Omit<First['signals'], FeatureResultKeys<Second>>;
87+
computed: Omit<First['computed'], FeatureResultKeys<Second>>;
9088
methods: Omit<First['methods'], FeatureResultKeys<Second>>;
9189
} & Second;

Diff for: ‎modules/signals/src/signal-store.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,8 @@ export function signalStore(
308308
(store, feature) => feature(store),
309309
getInitialInnerStore()
310310
);
311-
const { slices, signals, methods, hooks } = innerStore;
312-
const props = { ...slices, ...signals, ...methods };
311+
const { stateSignals, computedSignals, methods, hooks } = innerStore;
312+
const props = { ...stateSignals, ...computedSignals, ...methods };
313313

314314
(this as any)[STATE_SIGNAL] = innerStore[STATE_SIGNAL];
315315

@@ -335,8 +335,8 @@ export function signalStore(
335335
export function getInitialInnerStore(): InnerSignalStore {
336336
return {
337337
[STATE_SIGNAL]: signal({}),
338-
slices: {},
339-
signals: {},
338+
stateSignals: {},
339+
computedSignals: {},
340340
methods: {},
341341
hooks: {},
342342
};

Diff for: ‎modules/signals/src/with-computed.ts

+18-12
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,35 @@ import {
55
SignalsDictionary,
66
SignalStoreFeature,
77
SignalStoreFeatureResult,
8-
SignalStoreSlices,
8+
StateSignals,
99
} from './signal-store-models';
1010
import { Prettify } from './ts-helpers';
1111

1212
export function withComputed<
1313
Input extends SignalStoreFeatureResult,
14-
Signals extends SignalsDictionary
14+
ComputedSignals extends SignalsDictionary
1515
>(
1616
signalsFactory: (
17-
store: Prettify<SignalStoreSlices<Input['state']> & Input['signals']>
18-
) => Signals
19-
): SignalStoreFeature<Input, EmptyFeatureResult & { signals: Signals }> {
17+
store: Prettify<StateSignals<Input['state']> & Input['computed']>
18+
) => ComputedSignals
19+
): SignalStoreFeature<
20+
Input,
21+
EmptyFeatureResult & { computed: ComputedSignals }
22+
> {
2023
return (store) => {
21-
const signals = signalsFactory({ ...store.slices, ...store.signals });
22-
const signalsKeys = Object.keys(signals);
23-
const slices = excludeKeys(store.slices, signalsKeys);
24-
const methods = excludeKeys(store.methods, signalsKeys);
24+
const computedSignals = signalsFactory({
25+
...store.stateSignals,
26+
...store.computedSignals,
27+
});
28+
const computedSignalsKeys = Object.keys(computedSignals);
29+
const stateSignals = excludeKeys(store.stateSignals, computedSignalsKeys);
30+
const methods = excludeKeys(store.methods, computedSignalsKeys);
2531

2632
return {
2733
...store,
28-
slices,
29-
signals: { ...store.signals, ...signals },
34+
stateSignals,
35+
computedSignals: { ...store.computedSignals, ...computedSignals },
3036
methods,
31-
} as InnerSignalStore<Record<string, unknown>, Signals>;
37+
} as InnerSignalStore<Record<string, unknown>, ComputedSignals>;
3238
};
3339
}

Diff for: ‎modules/signals/src/with-hooks.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,23 @@ import {
33
EmptyFeatureResult,
44
SignalStoreFeature,
55
SignalStoreFeatureResult,
6-
SignalStoreSlices,
6+
StateSignals,
77
} from './signal-store-models';
88
import { Prettify } from './ts-helpers';
99

1010
type HookFn<Input extends SignalStoreFeatureResult> = (
1111
store: Prettify<
12-
SignalStoreSlices<Input['state']> &
13-
Input['signals'] &
12+
StateSignals<Input['state']> &
13+
Input['computed'] &
1414
Input['methods'] &
1515
StateSignal<Prettify<Input['state']>>
1616
>
1717
) => void;
1818

1919
type HooksFactory<Input extends SignalStoreFeatureResult> = (
2020
store: Prettify<
21-
SignalStoreSlices<Input['state']> &
22-
Input['signals'] &
21+
StateSignals<Input['state']> &
22+
Input['computed'] &
2323
Input['methods'] &
2424
StateSignal<Prettify<Input['state']>>
2525
>
@@ -47,8 +47,8 @@ export function withHooks<Input extends SignalStoreFeatureResult>(
4747
return (store) => {
4848
const storeProps = {
4949
[STATE_SIGNAL]: store[STATE_SIGNAL],
50-
...store.slices,
51-
...store.signals,
50+
...store.stateSignals,
51+
...store.computedSignals,
5252
...store.methods,
5353
};
5454
const hooks =

Diff for: ‎modules/signals/src/with-methods.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
SignalsDictionary,
88
SignalStoreFeature,
99
SignalStoreFeatureResult,
10-
SignalStoreSlices,
10+
StateSignals,
1111
} from './signal-store-models';
1212
import { Prettify } from './ts-helpers';
1313

@@ -17,8 +17,8 @@ export function withMethods<
1717
>(
1818
methodsFactory: (
1919
store: Prettify<
20-
SignalStoreSlices<Input['state']> &
21-
Input['signals'] &
20+
StateSignals<Input['state']> &
21+
Input['computed'] &
2222
Input['methods'] &
2323
StateSignal<Prettify<Input['state']>>
2424
>
@@ -27,18 +27,18 @@ export function withMethods<
2727
return (store) => {
2828
const methods = methodsFactory({
2929
[STATE_SIGNAL]: store[STATE_SIGNAL],
30-
...store.slices,
31-
...store.signals,
30+
...store.stateSignals,
31+
...store.computedSignals,
3232
...store.methods,
3333
});
3434
const methodsKeys = Object.keys(methods);
35-
const slices = excludeKeys(store.slices, methodsKeys);
36-
const signals = excludeKeys(store.signals, methodsKeys);
35+
const stateSignals = excludeKeys(store.stateSignals, methodsKeys);
36+
const computedSignals = excludeKeys(store.computedSignals, methodsKeys);
3737

3838
return {
3939
...store,
40-
slices,
41-
signals,
40+
stateSignals,
41+
computedSignals,
4242
methods: { ...store.methods, ...methods },
4343
} as InnerSignalStore<Record<string, unknown>, SignalsDictionary, Methods>;
4444
};

Diff for: ‎modules/signals/src/with-state.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,19 @@ export function withState<State extends object>(
3838
...state,
3939
}));
4040

41-
const slices = stateKeys.reduce((acc, key) => {
42-
const slice = computed(
41+
const stateSignals = stateKeys.reduce((acc, key) => {
42+
const sliceSignal = computed(
4343
() => (store[STATE_SIGNAL]() as Record<string, unknown>)[key]
4444
);
45-
return { ...acc, [key]: toDeepSignal(slice) };
45+
return { ...acc, [key]: toDeepSignal(sliceSignal) };
4646
}, {} as SignalsDictionary);
47-
const signals = excludeKeys(store.signals, stateKeys);
47+
const computedSignals = excludeKeys(store.computedSignals, stateKeys);
4848
const methods = excludeKeys(store.methods, stateKeys);
4949

5050
return {
5151
...store,
52-
slices: { ...store.slices, ...slices },
53-
signals,
52+
stateSignals: { ...store.stateSignals, ...stateSignals },
53+
computedSignals,
5454
methods,
5555
} as InnerSignalStore<State>;
5656
};

Diff for: ‎projects/ngrx.io/content/guide/signals/signal-store/custom-store-features.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -244,13 +244,13 @@ In addition to state, it's also possible to define expected computed properties
244244

245245
<code-example header="baz.feature.ts">
246246

247-
import { computed, Signal } from '@angular/core';
248-
import { signalStoreFeature, type, withComputed, withHooks } from '@ngrx/signals';
247+
import { Signal } from '@angular/core';
248+
import { signalStoreFeature, type, withMethods } from '@ngrx/signals';
249249

250250
export function withBaz() {
251251
return signalStoreFeature(
252252
{
253-
signals: type&lt;{ foo: Signal&lt;number> }&gt;(),
253+
computed: type&lt;{ foo: Signal&lt;number&gt; }&gt;(),
254254
methods: type&lt;{ bar(): void }&gt;(),
255255
},
256256
withMethods(({ foo, bar }) => ({

0 commit comments

Comments
 (0)
Please sign in to comment.