Skip to content

Commit 201fab3

Browse files
committed
Don't init child keyvals in first keyval body call
1 parent 9f5cfec commit 201fab3

File tree

4 files changed

+44
-22
lines changed

4 files changed

+44
-22
lines changed

packages/core/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ export { lens } from './lens';
55
export { lazy } from './lazy';
66
export { createContext, readContext, setContext } from './context';
77
export { spawn } from './spawn';
8-
export { InputType, KeyvalWithState } from './types';
8+
export type { InputType, KeyvalWithState } from './types';

packages/core/src/keyval.ts

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,29 @@ export function keyval<Input, ModelEnhance, Api, Shape>(
104104
isClone: boolean,
105105
cloneOf: Keyval<any, any, any, any> | null,
106106
) => {
107+
type Enriched = Input & ModelEnhance;
108+
type Output = {
109+
[K in keyof ModelEnhance]:
110+
| Store<ModelEnhance[K]>
111+
| Keyval<any, ModelEnhance[K], any, any>;
112+
};
113+
type KeyvalListState = ListState<Enriched, Output, Api>;
114+
const $entities = createStore<KeyvalListState>({
115+
items: [],
116+
instances: [],
117+
keys: [],
118+
});
119+
const $items = $entities.map(({ items }) => items);
120+
const $keys = $entities.map(({ keys }) => keys);
107121
return lazyInit(
108122
{
109123
type: 'keyval',
110124
api: 0,
111125
__lens: 0,
112126
__struct: 0,
113-
$items: 0,
114-
$keys: 0,
115-
__$listState: 0,
127+
$items,
128+
$keys,
129+
__$listState: $entities,
116130
defaultState: () => null as any,
117131
edit: 0,
118132
editField: 0,
@@ -141,12 +155,7 @@ export function keyval<Input, ModelEnhance, Api, Shape>(
141155
create,
142156
} = options as Exclude<typeof options, Keyval<any, any, any, any>>);
143157
}
144-
type Enriched = Input & ModelEnhance;
145-
type Output = {
146-
[K in keyof ModelEnhance]:
147-
| Store<ModelEnhance[K]>
148-
| Keyval<any, ModelEnhance[K], any, any>;
149-
};
158+
150159
let kvModel:
151160
| Model<
152161
{
@@ -157,7 +166,7 @@ export function keyval<Input, ModelEnhance, Api, Shape>(
157166
Shape
158167
>
159168
| undefined;
160-
type KeyvalListState = ListState<Enriched, Output, Api>;
169+
161170
if (create) {
162171
// @ts-expect-error typecast
163172
kvModel = model({ create });
@@ -174,11 +183,6 @@ export function keyval<Input, ModelEnhance, Api, Shape>(
174183
? null
175184
: getKeyRaw
176185
: kvModel.keyField;
177-
const $entities = createStore<KeyvalListState>({
178-
items: [],
179-
instances: [],
180-
keys: [],
181-
});
182186

183187
const api = createInstanceApi($entities, kvModel);
184188
const editApi = createEditApi(
@@ -213,8 +217,8 @@ export function keyval<Input, ModelEnhance, Api, Shape>(
213217
// @ts-expect-error bad implementation
214218
__lens: shape,
215219
__struct: structShape,
216-
$items: $entities.map(({ items }) => items),
217-
$keys: $entities.map(({ keys }) => keys),
220+
$items,
221+
$keys,
218222
__$listState: $entities as any,
219223
defaultState() {
220224
return kvModel?.defaultState() ?? (null as any);

packages/core/src/lazy.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,20 @@ type TypeMap = {
1515
effect: Effect<any, any, any>;
1616
};
1717

18-
let currentSkipLazyCb = true;
18+
export let currentSkipLazyCb = true;
19+
export let isRoot = true;
1920

2021
export function callInLazyStack<T extends () => any>(
2122
fn: T,
2223
skipLazyCb: boolean,
2324
): ReturnType<T> {
2425
const prevLazyCb = currentSkipLazyCb;
26+
const prevIsRoot = isRoot;
2527
currentSkipLazyCb = skipLazyCb;
28+
isRoot = false;
2629
const result = fn();
2730
currentSkipLazyCb = prevLazyCb;
31+
isRoot = prevIsRoot;
2832
return result;
2933
}
3034

packages/core/src/lazyInit.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { currentSkipLazyCb, isRoot } from './lazy';
2+
13
const queue: InitTask<any>[] = [];
24
let scheduled = false;
35

@@ -7,7 +9,15 @@ type InitTask<T> = {
79
initialized: boolean;
810
};
911

10-
const ignore = ['type', 'clone', 'isClone', 'cloneOf'];
12+
const ignore = [
13+
'type',
14+
'clone',
15+
'isClone',
16+
'cloneOf',
17+
'__$listState',
18+
'$items',
19+
'$keys',
20+
];
1121

1222
function runQueue() {
1323
for (const task of queue.splice(0)) {
@@ -29,8 +39,10 @@ function runQueue() {
2939
}
3040

3141
export function lazyInit<T extends object>(target: T, init: () => T): T {
42+
if (currentSkipLazyCb && !isRoot) {
43+
return target;
44+
}
3245
const task: InitTask<T> = { target, init, initialized: false };
33-
3446
queue.push(task);
3547
if (!scheduled) {
3648
scheduled = true;
@@ -44,7 +56,9 @@ export function lazyInit<T extends object>(target: T, init: () => T): T {
4456
if (!ignore.includes(key as any)) {
4557
Object.defineProperty(target, key, {
4658
get() {
47-
if (!task.initialized) runQueue();
59+
if (!task.initialized) {
60+
runQueue();
61+
}
4862
return target[key];
4963
},
5064
enumerable: true,

0 commit comments

Comments
 (0)