Skip to content

Commit 01d829e

Browse files
committed
adjust store
1 parent d090455 commit 01d829e

File tree

3 files changed

+52
-44
lines changed

3 files changed

+52
-44
lines changed

apps/examples/src/app/pages/cubes/index.page.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { Component, signal } from '@angular/core';
2-
import { NgtCanvas } from 'angular-three';
2+
import { NgtArgs, NgtCanvas } from 'angular-three';
3+
import { NgtsOrbitControls } from 'angular-three-soba/controls';
34

45
@Component({
56
standalone: true,
67
templateUrl: './scene.html',
8+
imports: [NgtsOrbitControls, NgtArgs],
79
})
810
class Scene {
911
hover = signal(false);

apps/examples/src/app/pages/cubes/scene.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
<ngt-spot-light [position]="[0, 1.5, 1.5]" [intensity]="5" />
1+
<ngt-spot-light #light [position]="[0, 1.5, 1.5]" [intensity]="5" />
2+
<ngt-spot-light-helper *args="[light, 'red']" />
23

34
<ngt-mesh
45
(beforeRender)="onBeforeRender($event.object)"
@@ -8,3 +9,5 @@
89
<ngt-box-geometry />
910
<ngt-mesh-lambert-material [color]="hover() ? 'hotpink' : 'orange'" />
1011
</ngt-mesh>
12+
13+
<ngts-orbit-controls />

libs/core/src/lib/utils/signal-store.ts

Lines changed: 45 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,9 @@ export type NgtSignalStore<State extends object> = {
6464
state: Signal<State>;
6565
};
6666

67-
export function signalStore<State extends object>(
68-
initialState:
69-
| Partial<State>
70-
| ((storeApi: Pick<NgtSignalStore<State>, 'get' | 'set' | 'patch'>) => Partial<State>) = {},
71-
options?: CreateSignalOptions<State>,
72-
): NgtSignalStore<State> {
73-
const setter = (_source: WritableSignal<State>) => (state: State | ((previous: State) => State)) => {
67+
const setter =
68+
<State extends object>(_source: WritableSignal<State>) =>
69+
(state: State | ((previous: State) => State)) => {
7470
const updater = (previous: State) => {
7571
const partial = typeof state === 'function' ? state(previous) : state;
7672
Object.keys(partial).forEach((key) => {
@@ -86,7 +82,9 @@ export function signalStore<State extends object>(
8682
});
8783
};
8884

89-
const patcher = (_source: WritableSignal<State>) => (state: State) => {
85+
const patcher =
86+
<State extends object>(_source: WritableSignal<State>) =>
87+
(state: State) => {
9088
const updater = (previous: State) => {
9189
Object.keys(state).forEach((key) => {
9290
const typedKey = key as keyof State;
@@ -101,14 +99,44 @@ export function signalStore<State extends object>(
10199
});
102100
};
103101

104-
const getter =
105-
(_source: WritableSignal<State>) =>
106-
(...keys: string[]) => {
107-
const root = untracked(_source);
108-
if (keys.length === 0) return root;
109-
return keys.reduce((value, key) => (value as NgtAnyRecord)[key], root);
110-
};
102+
const getter =
103+
<State extends object>(_source: WritableSignal<State>) =>
104+
(...keys: string[]) => {
105+
const root = untracked(_source);
106+
if (keys.length === 0) return root;
107+
return keys.reduce((value, key) => (value as NgtAnyRecord)[key], root);
108+
};
109+
110+
const selector =
111+
<State extends object>(_state: Signal<State>, computedCache: Map<string, Signal<any>>) =>
112+
(...keysAndOptions: any[]) => {
113+
if (keysAndOptions.length === 0) return _state;
114+
if (keysAndOptions.length === 1 && typeof keysAndOptions[0] === 'object') {
115+
const cachedKey = STORE_COMPUTED_KEY.concat(JSON.stringify(keysAndOptions[0]));
116+
if (!computedCache.has(cachedKey)) {
117+
computedCache.set(cachedKey, computed(_state, keysAndOptions as CreateComputedOptions<object>));
118+
}
119+
return computedCache.get(cachedKey)!;
120+
}
121+
const [keys, options] = parseStoreOptions(keysAndOptions);
122+
const joinedKeys = keys.join('-');
123+
const cachedKeys = joinedKeys.concat(options ? JSON.stringify(options) : '');
124+
125+
if (!computedCache.has(cachedKeys)) {
126+
computedCache.set(
127+
cachedKeys,
128+
computed(() => keys.reduce((value, key) => (value as NgtAnyRecord)[key], _state()), options),
129+
);
130+
}
131+
return computedCache.get(cachedKeys)!;
132+
};
111133

134+
export function signalStore<State extends object>(
135+
initialState:
136+
| Partial<State>
137+
| ((storeApi: Pick<NgtSignalStore<State>, 'get' | 'set' | 'patch'>) => Partial<State>) = {},
138+
options?: CreateSignalOptions<State>,
139+
): NgtSignalStore<State> {
112140
let source: WritableSignal<State>;
113141
let set: NgtSignalStore<State>['set'];
114142
let get: NgtSignalStore<State>['get'];
@@ -130,34 +158,9 @@ export function signalStore<State extends object>(
130158
const state = source.asReadonly();
131159
const computedCache = new Map();
132160

133-
const store = {
134-
select: (...keysAndOptions: any[]) => {
135-
if (keysAndOptions.length === 0) return state;
136-
if (keysAndOptions.length === 1 && typeof keysAndOptions[0] === 'object') {
137-
const cachedKey = STORE_COMPUTED_KEY.concat(JSON.stringify(keysAndOptions[0]));
138-
if (!computedCache.has(cachedKey)) {
139-
computedCache.set(cachedKey, computed(state, keysAndOptions as CreateComputedOptions<object>));
140-
}
141-
return computedCache.get(cachedKey)!;
142-
}
143-
const [keys, options] = parseStoreOptions(keysAndOptions);
144-
const joinedKeys = keys.join('-');
145-
const cachedKeys = joinedKeys.concat(options ? JSON.stringify(options) : '');
146-
147-
if (!computedCache.has(cachedKeys)) {
148-
computedCache.set(
149-
cachedKeys,
150-
computed(() => keys.reduce((value, key) => (value as NgtAnyRecord)[key], state()), options),
151-
);
152-
}
153-
return computedCache.get(cachedKeys)!;
154-
},
155-
get,
156-
set,
157-
patch,
158-
state,
159-
};
161+
const store = { select: selector(state, computedCache), get, set, patch, state };
160162

163+
// NOTE: internal _snapshot to debug current state
161164
Object.defineProperty(store, '_snapshot', {
162165
get: state,
163166
configurable: false,

0 commit comments

Comments
 (0)