Skip to content

Commit cd2a0de

Browse files
committed
Implement lens
1 parent 6794d9a commit cd2a0de

File tree

4 files changed

+38
-240
lines changed

4 files changed

+38
-240
lines changed

packages/core/src/keyval.ts

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,27 @@
11
import {
22
createStore,
33
createEvent,
4-
createEffect,
54
attach,
65
sample,
76
Store,
87
StoreWritable,
98
withRegion,
10-
combine,
119
clearNode,
1210
launch,
1311
EventCallable,
1412
Event,
15-
Effect,
16-
is,
1713
} from 'effector';
1814

1915
import type {
2016
Keyval,
2117
Model,
2218
StoreDef,
23-
EventDef,
24-
EffectDef,
2519
InstanceOf,
2620
Show,
2721
ConvertToLensShape,
2822
StructKeyval,
2923
} from './types';
3024
import { spawn } from './spawn';
31-
import { isDefine, isKeyval } from './define';
3225
import { model } from './model';
3326
import type { SetOptional } from './setOptional';
3427

@@ -308,21 +301,6 @@ export function keyval<Input, ModelEnhance, Api, Shape>(
308301
...inputUpdate,
309302
};
310303
freshState.items[idx] = newItem;
311-
if (kvModel) {
312-
const instance = freshState.instances[idx];
313-
// for (const key in instance.inputs) {
314-
// // @ts-expect-error cannot read newItem[key], but its ok
315-
// const upd = newItem[key];
316-
// // @ts-expect-error cannot read oldItem[key], but its ok
317-
// if (upd !== oldItem[key]) {
318-
// launch({
319-
// target: instance.inputs[key],
320-
// params: upd,
321-
// defer: true,
322-
// });
323-
// }
324-
// }
325-
}
326304
}
327305

328306
const addFx = attach({
@@ -497,19 +475,8 @@ export function keyval<Input, ModelEnhance, Api, Shape>(
497475
let structShape: any = null;
498476

499477
if (kvModel) {
500-
const initShape = {} as Record<string, any>;
501-
/** for in leads to typescript errors */
502-
Object.entries(kvModel.shape).forEach(([key, def]) => {
503-
if (isDefine.store(def)) {
504-
initShape[key] = createStore({});
505-
} else if (isDefine.event(def)) {
506-
initShape[key] = createEvent();
507-
} else if (isDefine.effect(def)) {
508-
initShape[key] = createEffect(() => {});
509-
}
510-
});
511478
// @ts-expect-error type issues
512-
const instance = spawn(kvModel, initShape);
479+
const instance = spawn(kvModel, {});
513480
clearNode(instance.region);
514481
structShape = {
515482
type: 'structKeyval',

packages/core/src/model.ts

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ import type {
1919
Show,
2020
ConvertToLensShape,
2121
FactoryPathMap,
22+
StructShape,
2223
} from './types';
23-
import { define, isDefine, isKeyval } from './define';
24+
import { define, isKeyval } from './define';
2425

2526
export function model<
2627
Input extends {
@@ -43,10 +44,8 @@ export function model<
4344
[key: string]: Event<unknown> | Effect<unknown, unknown, unknown>;
4445
} = {},
4546
>({
46-
props,
4747
create,
4848
}: {
49-
props: Input;
5049
create: (config: { onMount: Event<void> }) => {
5150
state: Output;
5251
api?: Api;
@@ -70,7 +69,6 @@ export function model<
7069
// }[keyof Output]]: Output[K];
7170
// }
7271
> {
73-
const shape = {} as any;
7472
const region = createNode({ regional: true });
7573
const {
7674
state = {} as Output,
@@ -110,6 +108,31 @@ export function model<
110108
isKeyval(state[field]),
111109
) as Array<keyof Output>;
112110

111+
const shape = {} as any;
112+
const structShape: StructShape = {
113+
type: 'structShape',
114+
shape: {},
115+
};
116+
for (const key in state) {
117+
shape[key] = define.store<any>();
118+
structShape.shape[key] = isKeyval(state[key])
119+
? state[key].__struct
120+
: {
121+
type: 'structUnit',
122+
unit: 'store',
123+
};
124+
}
125+
for (const key in api) {
126+
const value = api[key];
127+
shape[key] = is.event(value)
128+
? define.event<any>()
129+
: define.effect<any, any, any>();
130+
structShape.shape[key] = {
131+
type: 'structUnit',
132+
unit: is.event(value) ? 'event' : 'effect',
133+
};
134+
}
135+
113136
clearNode(region);
114137
return {
115138
type: 'model',
@@ -118,29 +141,12 @@ export function model<
118141
requiredStateFields,
119142
keyvalFields,
120143
factoryStatePaths,
121-
propsConfig: props,
122-
output: null as unknown as any,
123-
// api: null as unknown as any,
124144
shape,
125-
shapeInited: false,
126145
__lens: {} as any,
146+
__struct: structShape,
127147
};
128148
}
129149

130-
// function withInitState(fn) {
131-
// const initRegion = createNode({ regional: true });
132-
133-
// const state = withRegion(initRegion, () => fn());
134-
// const factoryPathToStateKey = collectFactoryPaths(state, initRegion);
135-
// clearNode(initRegion);
136-
137-
// return (initState: Record<string, any> = {}) => {
138-
// const region = createNode({ regional: true });
139-
// installStateHooks(initState, region, factoryPathToStateKey);
140-
// return [withRegion(region, () => fn()), region];
141-
// };
142-
// }
143-
144150
function collectFactoryPaths(state: Record<string, any>, initRegion: Node) {
145151
const factoryPathToStateKey: FactoryPathMap = new Map();
146152
for (const key in state) {

packages/core/src/spawn.ts

Lines changed: 8 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,10 @@ import type {
2020
EventDef,
2121
EffectDef,
2222
AnyDef,
23-
StructUnit,
24-
StructShape,
2523
FactoryPathMap,
2624
Keyval,
2725
} from './types';
28-
import { define, isDefine, isKeyval } from './define';
26+
import { isKeyval } from './define';
2927

3028
type ParamsNormalize<
3129
T extends {
@@ -114,187 +112,25 @@ export function spawn<
114112
): Instance<Output, Api> {
115113
const region = createNode({ regional: true });
116114
installStateHooks(params as any, region, model.factoryStatePaths);
117-
const normProps = {} as {
118-
[K in keyof T]: T[K] extends
119-
| Store<unknown>
120-
| Event<unknown>
121-
| Effect<unknown, unknown, unknown>
122-
? T[K]
123-
: T[K] extends StoreDef<infer V>
124-
? Store<V>
125-
: T[K] extends EventDef<infer V>
126-
? Event<V>
127-
: T[K] extends EffectDef<infer V, infer D, infer E>
128-
? Effect<V, D, E>
129-
: T[K] extends (params: infer P) => infer R
130-
? Effect<P, Awaited<R>>
131-
: Store<T[K]>;
132-
};
133-
let onMount: Event<void>;
134-
withRegion(region, () => {
135-
onMount = createEvent();
136-
// for (const key in model.propsConfig) {
137-
// const propModel = model.propsConfig[key];
138-
// //@ts-expect-error
139-
// const propParams = params[key];
140-
// const propParamsExist = key in params;
141-
// if (is.store(propModel)) {
142-
// if (propParamsExist) {
143-
// //@ts-expect-error
144-
// normProps[key] = getStoreParams(propParams);
145-
// } else {
146-
// //@ts-expect-error
147-
// normProps[key] = propModel;
148-
// }
149-
// } else if (is.event(propModel)) {
150-
// if (propParamsExist) {
151-
// /** Maybe we should allow to pass any unit to event field */
152-
// if (
153-
// is.event(propParams) ||
154-
// is.effect(propParams) ||
155-
// is.store(propParams)
156-
// ) {
157-
// normProps[key] = propParams;
158-
// } else {
159-
// throw Error(`spawn field "${key}" expect event`);
160-
// }
161-
// } else {
162-
// //@ts-expect-error
163-
// normProps[key] = propModel;
164-
// }
165-
// } else if (is.effect(propModel)) {
166-
// if (propParamsExist) {
167-
// //@ts-expect-error
168-
// normProps[key] = getEffectParams(key, propParams);
169-
// } else {
170-
// //@ts-expect-error
171-
// normProps[key] = propModel;
172-
// }
173-
// } else if (isDefine.store(propModel)) {
174-
// if (propParamsExist) {
175-
// //@ts-expect-error
176-
// normProps[key] = getStoreParams(propParams);
177-
// } else {
178-
// throw Error(`spawn field "${key}" expect store or value`);
179-
// }
180-
// } else if (isDefine.event(propModel)) {
181-
// if (propParamsExist && is.event(propParams)) {
182-
// normProps[key] = propParams;
183-
// } else {
184-
// throw Error(`spawn field "${key}" expect event`);
185-
// }
186-
// } else if (isDefine.effect(propModel)) {
187-
// if (propParamsExist) {
188-
// //@ts-expect-error
189-
// normProps[key] = getEffectParams(key, propParams);
190-
// } else {
191-
// throw Error(`spawn field "${key}" expect effect or function`);
192-
// }
193-
// } else if (typeof propModel === 'function') {
194-
// if (propParamsExist) {
195-
// //@ts-expect-error
196-
// normProps[key] = getEffectParams(key, propParams);
197-
// } else {
198-
// //@ts-expect-error
199-
// normProps[key] = createEffect(propModel);
200-
// }
201-
// } else {
202-
// if (propParamsExist) {
203-
// //@ts-expect-error
204-
// normProps[key] = getStoreParams(propParams);
205-
// } else {
206-
// //@ts-expect-error
207-
// normProps[key] = createStore(propModel);
208-
// }
209-
// }
210-
// }
211-
});
115+
const onMount = withRegion(region, () => createEvent());
212116
const parentTracking = childInstancesTracking;
213117
childInstancesTracking = [];
214118
const outputs = withRegion(region, () => model.create({ onMount: onMount! }));
215119
childInstancesTracking = parentTracking;
216-
let storeOutputs = {} as any;
217-
let apiOutputs = {} as any;
218-
/** its ok to not return anything */
219-
// if (outputs !== undefined) {
220-
// if (typeof outputs !== 'object' || outputs === null) {
221-
// throw Error(`model body should return object or undefined`);
222-
// }
223-
// if (
224-
// (outputs.state && !is.unit(outputs.state)) ||
225-
// (outputs.api && !is.unit(outputs.api))
226-
// ) {
227-
// storeOutputs = outputs.state ?? {};
228-
// apiOutputs = outputs.api ?? {};
229-
// } else {
230-
// storeOutputs = outputs;
231-
// }
232-
// for (const key in storeOutputs) {
233-
// const value = storeOutputs[key];
234-
// if (!is.store(value) && !isKeyval(value)) {
235-
// throw Error(`model body in state key "${key}" should return store`);
236-
// }
237-
// }
238-
// for (const key in apiOutputs) {
239-
// const value = apiOutputs[key];
240-
// if (!is.event(value) && !is.effect(value)) {
241-
// throw Error(
242-
// `model body in api key "${key}" should return event or effect`,
243-
// );
244-
// }
245-
// }
246-
// }
247-
if (!model.shapeInited) {
248-
model.shapeInited = true;
249-
const structShape: StructShape = {
250-
type: 'structShape',
251-
shape: {},
252-
};
253-
for (const key in normProps) {
254-
const unit = normProps[key];
255-
structShape.shape[key] = {
256-
type: 'structUnit',
257-
unit: is.store(unit) ? 'store' : is.event(unit) ? 'event' : 'effect',
258-
};
259-
}
260-
for (const key in storeOutputs) {
261-
// @ts-expect-error
262-
model.shape[key] = define.store<any>();
263-
structShape.shape[key] = isKeyval(storeOutputs[key])
264-
? storeOutputs[key].__struct
265-
: {
266-
type: 'structUnit',
267-
unit: 'store',
268-
};
269-
}
270-
for (const key in apiOutputs) {
271-
const value = apiOutputs[key];
272-
// @ts-expect-error
273-
model.shape[key] = is.event(value)
274-
? define.event<any>()
275-
: define.effect<any, any, any>();
276-
structShape.shape[key] = {
277-
type: 'structUnit',
278-
unit: is.event(value) ? 'event' : 'effect',
279-
};
280-
}
281-
model.__struct = structShape;
282-
}
120+
const storeOutputs = outputs.state ?? {};
121+
const apiOutputs = outputs.api ?? {};
283122
function forEachKeyvalField(
284123
cb: (kv: Keyval<any, any, any, any>, field: keyof Output) => void,
285124
) {
286-
const resultShape = {
287-
...(outputs.state ?? {}),
288-
} as Output;
289125
for (const field of model.keyvalFields) {
290-
if (isKeyval(resultShape[field])) {
291-
cb(resultShape[field], field);
126+
if (isKeyval(storeOutputs[field])) {
127+
cb(storeOutputs[field], field);
292128
}
293129
}
294130
}
295131
const $output = withRegion(region, () => {
296132
const resultShape = {
297-
...(outputs.state ?? {}),
133+
...storeOutputs,
298134
} as Output;
299135
forEachKeyvalField(({ $items }, field) => {
300136
// @ts-expect-error generic mismatch
@@ -314,9 +150,8 @@ export function spawn<
314150
output: $output,
315151
keyvalShape,
316152
props: storeOutputs,
317-
api: outputs.api ?? {},
153+
api: apiOutputs,
318154
region,
319-
inputs: normProps,
320155
};
321156
if (childInstancesTracking) {
322157
childInstancesTracking.push(result);

0 commit comments

Comments
 (0)