Skip to content

Commit

Permalink
Merge pull request #14 from luisherranz/fix-signal-assignment-artifacts
Browse files Browse the repository at this point in the history
Fix wrong artifacts on signal assignment
  • Loading branch information
DAreRodz committed Jan 26, 2023
2 parents 401675a + df9d65b commit 91a45cb
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 27 deletions.
5 changes: 5 additions & 0 deletions .changeset/green-lemons-build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"deepsignal": patch
---

Fix wrong artifacts being generated on signal assignments. _Bug spotted by @DAreRodz._
33 changes: 18 additions & 15 deletions packages/deepsignal/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,25 +70,28 @@ const mutationError = "Don't mutate the signals directly.";

const objectHandlers = {
get: get(false),
set(target: object, key: string, val: any, receiver: object) {
let internal = val;
set(target: object, fullKey: string, val: any, receiver: object) {
if (!proxyToSignals.has(receiver)) proxyToSignals.set(receiver, new Map());
const signals = proxyToSignals.get(receiver);
if (key[0] === "$") {
if (fullKey[0] === "$") {
if (!(val instanceof Signal)) throw new Error(mutationError);
internal = val.value;
signals.set(key.replace(rg, ""), val);
} else if (shouldProxy(val)) {
if (!objToProxy.has(val))
objToProxy.set(val, new Proxy(val, objectHandlers));
internal = objToProxy.get(val);
const key = fullKey.replace(rg, "");
signals.set(key, val);
return Reflect.set(target, key, val.peek(), receiver);
} else {
let internal = val;
if (shouldProxy(val)) {
if (!objToProxy.has(val))
objToProxy.set(val, new Proxy(val, objectHandlers));
internal = objToProxy.get(val);
}
if (!signals.has(fullKey)) signals.set(fullKey, signal(internal));
else signals.get(fullKey).value = internal;
const result = Reflect.set(target, fullKey, val, receiver);
if (Array.isArray(target) && signals.has("length"))
signals.get("length").value = target.length;
return result;
}
if (!signals.has(key)) signals.set(key, signal(internal));
else signals.get(key).value = internal;
const result = Reflect.set(target, key, val, receiver);
if (Array.isArray(target) && signals.has("length"))
signals.get("length").value = target.length;
return result;
},
};

Expand Down
10 changes: 10 additions & 0 deletions packages/deepsignal/core/test/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,16 @@ describe("deepsignal/core", () => {
expect(store.a).to.equal(2);
expect(store.$a).to.equal(a);
});

it("should not create wrong artifacts when assigning signals", () => {
const store = deepSignal<{ a?: number }>({});
const a = signal(1);

store.$a = a;

expect(peek(store as any, "$a")).to.equal(undefined);
expect(peek(store, "a")).to.equal(1);
});
});

describe("computations", () => {
Expand Down
35 changes: 23 additions & 12 deletions packages/deepsignal/core/test/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Signal } from "@preact/signals-core";
import { signal, Signal } from "@preact/signals-core";
import { deepSignal, peek } from "../src";

// Arrays.
Expand Down Expand Up @@ -44,22 +44,33 @@ const a27: Signal<number> = array.reduceRight(
array.$0;

// Normal functions.
const store = deepSignal({
const store1 = deepSignal({
value: 1,
isBigger: (newValue: number): boolean => store.value > newValue,
isBigger: (newValue: number): boolean => store1.value > newValue,
sum(newValue: number): number {
return store.value + newValue;
return store1.value + newValue;
},
valueSignal: (): Signal<number> => store.$value!,
valueSignal: (): Signal<number> => store1.$value!,
nested: {
toString: (): string => `${store.value}`,
toString: (): string => `${store1.value}`,
},
});
const s1: boolean = store.isBigger(2);
const s2: number = store.sum(2);
const s3: Signal<number> = store.valueSignal();
const s4: string = store.toString();
const s1: boolean = store1.isBigger(2);
const s2: number = store1.sum(2);
const s3: Signal<number> = store1.valueSignal();
const s4: string = store1.toString();
// @ts-expect-error
store.isBigger!.value();
store1.isBigger!.value();
// @ts-expect-error
store.nested.$toString!.value();
store1.nested.$toString!.value();

// Signal assignments.
const store2 = deepSignal<{ a?: number }>({});
const a = signal(1);

// @ts-expect-error
store2.a = a;

store2.$a = a;
const s5: number = store2.a!;
const s6: Signal<number | undefined> = store2.$a;

0 comments on commit 91a45cb

Please sign in to comment.