Skip to content

Commit

Permalink
chore: hook params alpha impl
Browse files Browse the repository at this point in the history
  • Loading branch information
betula committed Dec 23, 2023
1 parent 4f3c96c commit 76d8664
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 13 deletions.
17 changes: 11 additions & 6 deletions src/hook.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
import React from 'react';
import { collect, unsubscriber, run } from 'unsubscriber';
import { signal, wrap, SignalReadonly } from './signal';

export const hook = <T>(Class: (() => T) | (new () => T)): (() => T) => {
export const hook = <T>(Class: ((params?: SignalReadonly<any>) => T) | (new (params?: SignalReadonly<any>) => T)): ((params?: any) => T) => {

return () => {
const [instance, unsubs] = React.useMemo(() => {
return (params: any) => {
const [instance, unsubs, signalParams] = React.useMemo(() => {
const signalParams = signal(params);
const wrapped = wrap(signalParams.get);
const unsubs = unsubscriber();
return [
collect(unsubs, () => (
Class.prototype === void 0
? (Class as () => T)()
: new (Class as new () => T)()
? (Class as (params?: SignalReadonly<any>) => T)(wrapped)
: new (Class as new (params?: SignalReadonly<any>) => T)(wrapped)
)),
unsubs
unsubs,
signalParams
]
}, []);

React.useEffect(() => () => run(unsubs), [unsubs]);
signalParams(params);
return instance;
}
}
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export {
type Signal,
type ReadonlySignal,
type SignalReadonly,
signal,
wrap
} from './signal';
Expand Down
12 changes: 6 additions & 6 deletions src/signal.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { observable, untracked, computed as mobxComputed, comparer } from 'mobx';
import { reaction, sync } from './reaction';

export interface ReadonlySignal<T> {
export interface SignalReadonly<T> {
get value(): T;
get(): T;
subscribe(listener: (current: T, prev: T) =>void): () => void;
sync(listener: (current: T, prev: T | undefined) =>void): () => void;
}

export interface Signal<T> extends ReadonlySignal<T> {
export interface Signal<T> extends SignalReadonly<T> {
(value: T): T,
update(fn: (value: T) => T);
}
Expand All @@ -20,17 +20,17 @@ export function signal<T>(value: T): Signal<T> {
return make(get, set);
}

export function wrap<T>(readfn: () => T): ReadonlySignal<T>;
export function wrap<T>(readfn: () => T): SignalReadonly<T>;
export function wrap<T>(readfn: () => T, writefn: (value: T) => void): Signal<T>;
export function wrap<T>(readfn: () => T, writefn?: (value: T) => void): (ReadonlySignal<T> | Signal<T>) {
export function wrap<T>(readfn: () => T, writefn?: (value: T) => void): (SignalReadonly<T> | Signal<T>) {
const box = mobxComputed(readfn, { equals: comparer.shallow });
const get = box.get.bind(box);
return make(get, writefn);
}

function make<T>(readfn: () => T): ReadonlySignal<T>;
function make<T>(readfn: () => T): SignalReadonly<T>;
function make<T>(readfn: () => T, writefn: (value: T) => void): Signal<T>;
function make<T>(readfn: () => T, writefn?: (value: T) => void): (ReadonlySignal<T> | Signal<T>) {
function make<T>(readfn: () => T, writefn?: (value: T) => void): (SignalReadonly<T> | Signal<T>) {
const get = readfn;
const h = writefn || {};
Object.defineProperty(h, 'value', { get })
Expand Down

0 comments on commit 76d8664

Please sign in to comment.