Skip to content

Commit f307c93

Browse files
refactored functionalComponents and signals logic a little
1 parent 250a21a commit f307c93

File tree

5 files changed

+58
-62
lines changed

5 files changed

+58
-62
lines changed

src/rendering/createElements.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import { isValidStyle, preprocessStyle, styleObjectToString } from "../lib";
2-
import { setReactiveAttributes } from "../signals/batch";
3-
import { reactive, reactiveAttribute, Ref } from "../signals/signal";
1+
import { reactive, Ref } from "../signals/signal";
42
import {
53
Fiber,
64
FiberChildren,

src/rendering/functionalComponents.ts

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ export function getCurrentFC() {
2222
return currentFC;
2323
}
2424

25+
function getNewFC(): any {
26+
return {
27+
signals: new Set(),
28+
cleanup: [],
29+
effects: new Set(),
30+
};
31+
}
32+
2533
export function runAllEffects(FC: Fiber) {
2634
if (fcMap.has(FC)) {
2735
const fcData = fcMap.get(FC)!;
@@ -36,64 +44,46 @@ export function cleanUp(fn: Function) {
3644
if (currentFC) {
3745
// console.log(currentFC, fcMap.has(currentFC));
3846
if (fcMap.has(currentFC)) {
39-
const fcData = fcMap.get(currentFC)!;
40-
41-
fcData.cleanup.push(fn);
47+
fcMap.get(currentFC)!.cleanup.push(fn);
4248
} else {
43-
fcMap.set(currentFC, {
44-
signals: new Set(),
45-
cleanup: [fn],
46-
effects: new Set(),
47-
});
49+
let newFC = getNewFC();
50+
newFC.cleanup.push(fn);
51+
fcMap.set(currentFC, newFC);
4852
}
4953
}
5054
}
5155
export function cleanUpWFiber(fn: Function, fiber: Fiber) {
5256
if (fiber) {
5357
// console.log(currentFC, fcMap.has(currentFC));
5458
if (fcMap.has(fiber)) {
55-
const fcData = fcMap.get(fiber)!;
56-
57-
fcData.cleanup.push(fn);
59+
fcMap.get(fiber)!.cleanup.push(fn);
5860
} else {
59-
fcMap.set(fiber, {
60-
signals: new Set(),
61-
cleanup: [fn],
62-
effects: new Set(),
63-
});
61+
let newFC = getNewFC();
62+
newFC.cleanup.push(fn);
63+
fcMap.set(fiber, newFC);
6464
}
6565
}
6666
}
6767

6868
export function addEffect(fn: Function) {
6969
if (currentFC) {
7070
if (fcMap.has(currentFC)) {
71-
const fcData = fcMap.get(currentFC)!;
72-
fcData.effects.add(fn);
71+
fcMap.get(currentFC)!.effects.add(fn);
7372
} else {
74-
const effects = new Set<Function>();
75-
effects.add(fn);
76-
fcMap.set(currentFC, {
77-
signals: new Set(),
78-
cleanup: [],
79-
effects: effects,
80-
});
73+
let newFC = getNewFC();
74+
newFC.effects.add(fn);
75+
fcMap.set(currentFC, newFC);
8176
}
8277
}
8378
}
8479
export function addSignal(signal: BaseSignal<any>) {
8580
if (currentFC) {
8681
if (fcMap.has(currentFC)) {
87-
const fcData = fcMap.get(currentFC)!;
88-
fcData.signals.add(signal);
82+
fcMap.get(currentFC)!.signals.add(signal);
8983
} else {
90-
const signals = new Set<BaseSignal<any>>();
91-
signals.add(signal);
92-
fcMap.set(currentFC, {
93-
signals: signals,
94-
cleanup: [],
95-
effects: new Set(),
96-
});
84+
let newFC = getNewFC();
85+
newFC.signals.add(signal);
86+
fcMap.set(currentFC, newFC);
9787
}
9888
}
9989
}
@@ -112,7 +102,7 @@ export function cleanUpFC(currentFC, props) {
112102

113103
for (const effect of fcData.effects) {
114104
// @ts-expect-error
115-
if (effect.__cleanup && typeof effect.__cleanup === "function") {
105+
if (effect.__cleanup) {
116106
// @ts-expect-error
117107
effect.__cleanup();
118108
}

src/signals/signal.ts

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ import { isPlainObject, isPrimitive } from "../utils/general";
1010
import { batchUpdate } from "./batch";
1111
import {
1212
createArrayProxy,
13-
MutatingMethods,
1413
publicSignal,
1514
throwInvalidSignalType,
1615
throwNonPrimitiveError,
16+
throwNotArray,
17+
throwNotObject,
18+
throwNotUpdateCalled,
1719
} from "./utils";
1820

1921
let currentReactiveFunction: any = null;
@@ -288,9 +290,7 @@ export class ArraySignal<T extends any[]> extends BaseSignal<T> {
288290

289291
constructor(val: T) {
290292
if (!Array.isArray(val)) {
291-
throw new Error(
292-
"Invalid type for ArraySignal; value must be an array"
293-
);
293+
throwNotArray();
294294
}
295295
// Call the base constructor with a proxy-wrapped array.
296296
super(val);
@@ -307,9 +307,7 @@ export class ArraySignal<T extends any[]> extends BaseSignal<T> {
307307
val(this._val);
308308
} else {
309309
if (!Array.isArray(val)) {
310-
throw new Error(
311-
"Invalid type for ArraySignal; value must be an array"
312-
);
310+
throwNotArray();
313311
}
314312
if (val === this._val) return;
315313

@@ -328,9 +326,7 @@ export class ObjectSignal<T extends Record<any, any>> extends BaseSignal<T> {
328326
private updateCalled: boolean = false;
329327
constructor(val: T) {
330328
if (!isPlainObject(val)) {
331-
throw new Error(
332-
"Invalid type for ObjectSignal; value must be a plain object"
333-
);
329+
throwNotArray();
334330
}
335331
super(val);
336332
this._val = this.createProxy(val);
@@ -354,9 +350,7 @@ export class ObjectSignal<T extends Record<any, any>> extends BaseSignal<T> {
354350
},
355351
set: (target, prop, newValue) => {
356352
if (!this.updateCalled) {
357-
throw new Error(
358-
"Cannot set a value on an object signal, use the update method for updating the object."
359-
);
353+
throwNotUpdateCalled();
360354
}
361355
// Do not allow functions to be set as values.
362356
if (typeof newValue === "function") return false;
@@ -386,9 +380,7 @@ export class ObjectSignal<T extends Record<any, any>> extends BaseSignal<T> {
386380
val(this._val);
387381
} else {
388382
if (!isPlainObject(val)) {
389-
throw new Error(
390-
"Invalid type for ObjectSignal; value must be a plain object"
391-
);
383+
throwNotObject();
392384
}
393385
if (val === this._val) return;
394386
this._val = this.createProxy(val);
@@ -423,10 +415,6 @@ function createSignal<T extends Record<any, any>>(
423415
function createSignal<T extends NormalSignal | any[] | Record<any, any>>(
424416
val: T
425417
) {
426-
if (typeof val === "function") {
427-
throw new Error("Functions cannot be used as signal value");
428-
}
429-
430418
if (typeof val === "object" && val !== null) {
431419
if (Array.isArray(val)) {
432420
const signal = new ArraySignal(val);

src/signals/utils.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,34 @@ function isMutating(prop: any) {
1616
return MutatingMethods.includes(String(prop));
1717
}
1818

19+
const isProd =
20+
// @ts-expect-error
21+
process.env.NODE_ENV === "production" ||
22+
// @ts-expect-error
23+
import.meta.env.MODE === "production";
24+
1925
export function throwNonPrimitiveError() {
26+
if (isProd) return;
2027
throw new Error(
2128
"Invalid type for PrimitiveSignal. Valid types: [boolean, string, number, undefined, null]"
2229
);
2330
}
31+
export function throwNotUpdateCalled() {
32+
if (isProd) return;
33+
throw new Error(
34+
"Cannot set a value on a signal, use the update method instead."
35+
);
36+
}
37+
export function throwNotArray() {
38+
if (isProd) return;
39+
throw new Error("Invalid type for ArraySignal; value must be an array");
40+
}
41+
export function throwNotObject() {
42+
if (isProd) return;
43+
throw new Error("Invalid type for ObjectSignal; value must be an object");
44+
}
2445
export function throwInvalidSignalType(val: any) {
46+
if (isProd) return;
2547
throw new Error("Invalid type for signal initialization: " + typeof val);
2648
}
2749

src/tests/signals/signal.test.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe("Signal", () => {
2525
it("should not create a signal with function", () => {
2626
expect(() => {
2727
createSignal(() => 0);
28-
}).toThrow("Functions cannot be used as signal value");
28+
}).toThrow();
2929
});
3030
it("should should create Normal Signal for primitive and null values", () => {
3131
const values = [0, "", false, null, undefined];
@@ -55,9 +55,7 @@ describe("Signal", () => {
5555
objectSignal.update(2);
5656
objectSignal.update([1, 2]);
5757
};
58-
expect(assignWrongValue).toThrow(
59-
"Invalid type for ObjectSignal; value must be a plain object"
60-
);
58+
expect(assignWrongValue).toThrow();
6159
});
6260
it("should throw when creating effect without function", () => {
6361
const wrongEffect = () => createEffect(1);

0 commit comments

Comments
 (0)