Skip to content

Commit

Permalink
feat: added signal.get/set methods, aliased as signal.r/w
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasklaen committed Jan 30, 2024
1 parent 2063838 commit 77c5171
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 15 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ interface Signal<T extends unknown = unknown> {
value: T;
changed: () => void;
edit: (editor: (value: T) => void) => void;
// Aliases
get: () => T;
r: () => T;
set: (value: T) => void;
w: (value: T) => void;
}
```

Expand Down
34 changes: 19 additions & 15 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,14 @@ export type Action<T extends unknown> = (dispose: Disposer) => T;
export interface Signal<T extends unknown = unknown> {
/** Read value. */
(): T;
/** Read value. */
get: () => T;
r: () => T;
/** Set value. */
(value: T): void;
/** Set value. */
set: (value: T) => void;
w: (value: T) => void;
/** Non-reactive reference to value. */
value: T;
/** Manually triggers value change signal. */
Expand Down Expand Up @@ -264,10 +270,21 @@ export function signal<T extends unknown>(value: T): Signal<T> {
function getSet(): T;
function getSet(value: T): void;
function getSet(value?: T) {
return arguments.length ? write(value!) : read();
return arguments.length ? getSet.w(value!) : getSet.r();
}

getSet.value = value;
getSet.get = getSet.r = () => {
registerDependency(getSet);
return getSet.value;
};
getSet.set = getSet.w = (value: T) => {
if (disallowWrites) throw new Error(`Writing to signals not allowed in this context.`);
if (value !== getSet.value) {
getSet.value = value;
getSet.changed();
}
};
getSet.changed = () => {
if (!effectQueue) bulkEffects(() => triggerObservers(getSet));
else triggerObservers(getSet);
Expand All @@ -276,20 +293,7 @@ export function signal<T extends unknown>(value: T): Signal<T> {
editor(getSet.value);
getSet.changed();
};
getSet.toJSON = () => toJSON(read());

function read() {
registerDependency(getSet);
return getSet.value;
}

function write(value: T) {
if (disallowWrites) throw new Error(`Writing to signals not allowed in this context.`);
if (value !== getSet.value) {
getSet.value = value;
getSet.changed();
}
}
getSet.toJSON = () => toJSON(getSet.r());

return getSet;
}
Expand Down
22 changes: 22 additions & 0 deletions test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,34 @@ test(`calling a signal with no argument reads it`, (t) => {
t.is(s(), 'foo');
});

test(`signal.get reads the signal`, (t) => {
const s = signal('foo');
t.is(s.get(), 'foo');
});

test(`signal.r() is an alias of signal.get()`, (t) => {
const s = signal('foo');
t.is(s.get, s.r);
});

test(`calling a signal with one argument sets it`, (t) => {
const s = signal('foo');
s('bar');
t.is(s(), 'bar');
});

test(`signal.set(value) sets the signal`, (t) => {
const s = signal('foo');
s.set('bar');
t.is(s(), 'bar');
});

test(`signal.w() is an alias of signal.set()`, (t) => {
const s = signal('foo');
s.set('bar');
t.is(s.set, s.w);
});

test(`signal.value points to the current value`, (t) => {
const obj = {};
const s = signal<any>(obj);
Expand Down

0 comments on commit 77c5171

Please sign in to comment.