Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

low: the stream of conciseness 0.7+ roadmap #88

Open
betula opened this issue Apr 23, 2021 · 48 comments
Open

low: the stream of conciseness 0.7+ roadmap #88

betula opened this issue Apr 23, 2021 · 48 comments

Comments

@betula
Copy link
Member

betula commented Apr 23, 2021

"ready" -> "trigger"
"sub" -> "update.by"

// cast -- to
v.cast.signal.trigger()
v.cast.value.trigger()
v.to(console.log);
value(0).view()
value(0).view.untrack()

value(0).flow() //-- stoppable
value(0).flow.untrack()
value(0).flow.filter()
value(0).flow.filter.untrack()
value(0).flow.filter.not()
value(0).flow.filter.not.untrack()

value(0).chan() //-- stoppable
value(0).chan.untrack()
value(0).chan.filter()
value(0).chan.filter.untrack()
value(0).chan.filter.not()
value(0).chan.filter.not.untrack()

value(0).chan.debounce(300)
value(0).chan.throttle(300)

value(0).pre() //-- stoppable (untracked by default) expression
value(0).pre.track()

value(0).pre.filter()
value(0).pre.filter.untrack()
value(0).pre.filter.not()
value(0).pre.filter.not.untrack()

value(0).pre.chan()
value(0).pre.chan.untrack()
value(0).pre.chan.filter()
value(0).pre.chan.filter.untrack()
value(0).pre.chan.filter.not()
value(0).pre.chan.filter.not.untrack()

value(0).pre.chan.debounce(300)
value(0).pre.chan.throttle(300)
value(0).to.signal()
value(0).to.value()
value(0).to.ready()
value(0).to.flag()
value(0).to.flag.not()

value(0).promise

value(0).join(a, b)
value(0).join.chan(a, b)
value(0).join.signal(a, b)
value(0).join.signal.ready(a, b)
value(0).join.value(a, b)
value(0).join.value.ready(a, b)

value(0).sync(b)

value(0).interceptor()
value(0).sub.interceptor()

value(0).sub()
value(0).sub.once()

value(0).watch()
value(0).watch.once()
value()
value.from()
value.ready()
value.ready.from()
value.ready.flag()
value.ready.flag.from()
value.flag()
value.flag.from()

signal()
signal.from()
signal.ready()              // proposal: ready to trigger rename?
signal.ready.from()
signal.ready.flag()
signal.ready.flag.from()
signal.flag()
signal.flag.from()
pool()

pool().pre.throttle()
pool().pre.pipe(pool(), pool())
pool().pipe(pool(), pool())
@betula
Copy link
Member Author

betula commented May 22, 2021

Backlog from api-0.6 implementation

  [] trigger should be touchable
  [] value.touchable(initial) <- The ".from" construction not available for values with "initial" dependency requireds
  [] signal.touchable(initial)
  [] v.as.readonly()
  [] flow.resolve
  [] flow as root level exportable factory function
  [] .chan
  [] value.trigger.from
  [] value.trigger.flag.from
  [] .map <- sysnonym for .view (on thinking)
  [] x.group -- x.op -- x.block
    x.block((ctx) => ({  // if returns non undefined
      a: ctx.a,
      b: ctx.a.select()
    })).b.val
  [] v.as.signal(), v.as.trigger.flag()

@betula
Copy link
Member Author

betula commented Jun 3, 2021

Backlog:
[] Add callback to join, and combine. After It possible to use object config for join with callback
[] .as.trigger
[] .as.value.trigger
[] .as.signal.trigger

[] signal.trigger.resolved
[] value.trigger.resolved

[] test case "should work signal.trigger with configured .pre"

[] signal.trigger.from
[] value.trigger.from

[] Add Loader example to documentation

  // Second example
  const Loader = () => {
    const count = value(0);

    return {
      start: count.updater(v => v + 1),
      stop: count.updater(v => v - 1),
      pending: count.select(v => v > 0)
    }
  }

@betula
Copy link
Member Author

betula commented Jun 6, 2021

Join brainstorm:

[] Add track|untrack for join with callback

I think better way in that case is removing callback support for current version.
because without callback for combine and join no have any conficts for syntax.
I can use track|untrack for join without callback with no disharmony

--> decision for version 0.6:
  [] remove callback support for join and combine
  [] Add track|untrack for join
    ...disharmony was stay
--> decision number two) The second
  [] rename join to "attach" or "merge"

    Task: The saving consistency of track|untrack for append|attach|join|merge function

    Have a reason for join without tracking for a set of rective values.

      Have a reason join for signals?

value.combine() -> ok
value.join() -> ok

I cant implement signal.combine([], fn and s.join([], fn) because I have not flag for ready all
signals from argument

signal.combine() -> not ok
signal.join() -> not ok

maybe support combine and join only for values now.
For signal I can use merge

const s = signal(0);
s.merge([() => s.val, ...]).val == 0; without callback

Summary:
[] I should implement value.combine([]|{}, fn?), and value(0).combine([] | {}, fn?)
- track|untrack for combine? (I can not support untrack for combine values)

[] No have similar for signal in 0.6 versions.

value.from(() => ({
a: a.val,
b: b.val
}))
value.combine({ a, b }) -> better...
Always tracked, and it used only for values

value(0).combine - have a problem with track|untrack semantic not for 0.6 version.

I should make only value.combine. Aren't It?
Ok. For 0.6 its enough

@betula
Copy link
Member Author

betula commented Jun 6, 2021

Backlog
[] as.value(dafault_value?)
[] support reactionable for untrack
[] value().get.untrack()

@betula
Copy link
Member Author

betula commented Jun 6, 2021

Backlog
[] Add default for resolve "Will" type

  const v = value(0).filter().default(0)

@betula
Copy link
Member Author

betula commented Jun 7, 2021

Backlog:

const r = signal();
const u = signal<number>();

const v = value(0);

v.reset.by(r);

v.update.by(u, (state, up_value, up_value_prev) => {
  return state + (up_value - (up_value_prev || 0));
});

u(10);
r();

And I think to very interesting idea is the convert "reset" function method to signal

const a = value(0);

a.reset.to(() => console.log("reset"));

@betula betula changed the title low: api extendable list (0.6-0.7 roadmap) low: the stream of conciseness 0.7+ roadmap Jun 7, 2021
@betula
Copy link
Member Author

betula commented Jun 7, 2021

proposal: local

cosnt v = value(0);

v.flow((value) => {
  const ticket = local(() => wait(k));
  if (!ticket.val) return flow.stop();
  return value;
});

v.flow.filter(() => {
  return local(() => wait(k)).val
});

local(expr) // <- bind only first time not necessary bind it every time
                   // if you need bind every time you should use plain function not local expression.
                   // synonim of local(expr, []);
local(expr, [<real value dep>, ...])
local(expr, <refresh symbol or expression>);

// or all combination of that
local(expr, <refresh symbol or expression>, [<real value dep>, ...]);
local(expr, [<real value dep>, ...], <refresh symbol or expression>);

@betula
Copy link
Member Author

betula commented Jun 7, 2021

proposal: wait

const v = value(0);
const s = signal(0);

// wait.all([v, s]) - it is a ready (trigger)

await wait.all([v, s]).promise
await wait.once([v, s]).promise

wait(v) // similar to signal.trigger.from(v) or v.to.signal.trigger()
const k = signal(0);
const m = value(0);

v.flow.wait(m)
  .flow.wait.all(k, m) // or synonim to .flow.wait.all([k, m]) -- think about
  .flow.wait.race(k, m)
  .to((v) => console.log(v));
const k = signal(0);
const m = value(0);

v.flow.wait(m, (v_val, m_val) => return v_val + m_val)
  .flow.wait.all([k, m], (v_val, [k_val, m_val]) => return v_val + k_val + m_val) // or stop of course (maybe I can get resolve???)
  .flow.wait.race([k, m], (v_val, [k_val, m_val], resolve, v_val_prev) => {});
  .to((v) => console.log(v));

@betula
Copy link
Member Author

betula commented Jun 7, 2021

up: replace useMemo by useRef

You may rely on useMemo as a performance optimization, not as a semantic guarantee. In the future, React may choose to “forget” some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components. Write your code so that it still works without useMemo — and then add it to optimize performance.

@betula
Copy link
Member Author

betula commented Jun 7, 2021

proposal: chain

Think about "chain" abstraction

const a = value(0);
const b = chain(() => a.val);

assert(b.val === undefined);
a(5);
assert(b.val === undefined);

b.input.to(b.output); // "to" better than "watch"
a(6);
assert(b.val === 6);

@betula
Copy link
Member Author

betula commented Jun 7, 2021

proposal: pool.flat

private finish_purchase = pool(async () => {
    if (this.finish_purchase.count > 1) return; // not count.val here
  });
const a = pool(async () => {
    if (a.count.val > 1) return a.threads[0].promise; // Return promise from first thread
}

assert(a.flat.pending === false);
assert(chan(async () => {}).flat.pending === false);

@betula
Copy link
Member Author

betula commented Jun 7, 2021

proposal: signal.union

Collect signals from several values and signals.
Worked as last value of set

const a = value(0);
const b = signal(0);

const u = signal.union(a, b);

u.val === 0;
a(5);
u.val === 5;
b(10);
u.val === 10;

@betula
Copy link
Member Author

betula commented Jun 7, 2021

proposal: chan

Chan - is therm for define async flow.
Previous proposals for async are "flow.async", pipe.

const a = chan(async (p, k, m) => {}, empty_val?);
a(1,2,3);

const b = a.chan(async (a_val, prev_a_val) => {
});

chan(async () => {})
  .flow.filter()
  .flow.filter.untrack(() => this.loaded)
  .watch.once(() => {});

chan.untrack(async () => {})
  .join(b)
  .select(([a,b]) => a + b)
  .flow.untrack(() => {}, empty_val?)
  .watch(() => {})

chan(async () => {}).wrap.filter.not()

// ...

chan.untrack(async () => {}, empty_val)

value.from(() => {})
  .chan(async () => {}, empty_val)
  .flow.untrack(() => {}, empty_val?)
  .flow((a) => a + b.val)
  .watch(() => {});

Chan is not a "pool" because "chan" provides only one value, and flows around that value. Overwise "pool" provides a group of parallel or series async execution processes.

But both these meanings can be used with similar async operators.

const t = value(0)
  .view(() => {})
  .wrap.throttle(300)
  .chan.debounce(300);

// .flow.debounce(300); ??

// const t = pool(async () => {})        // "pool" untracked by default for safety reason
//  .wrap.throttle // hmmm multiples of parameters and throttle can be strange combination.
// Necessary to think about "throttle" and "debounce" for "pool".

Possible typecast syntax

chan(async () => {}).select.untrack(() => {});

signal(0).to.value()     // vs "signal(0).to.value"
value(0).to.signal()
signal(0).to.ready()

signal(0).promise
value(0).promise
value(0).to.ready().promise      // promise recreate on demand     // vs value(0).to.ready.promise

value.flag()
value.flag.not()
value.ready()
signal.flag()            // equivalent to "value.flag"
signal.ready()

// Think about rename "value.ready" to "value.once" or "value.trigger" ...

signal(0).to.trigger()  // The primary candidate for changing to
signal(0).to.once()     // hmm..

@betula
Copy link
Member Author

betula commented Jun 7, 2021

low: proposal pool single and pool static chaining factory

pool.single(async () => {

})

// or

pool(async () => {

}).single()

// Will be same result
pool.debounce(300).single().flow(async () => {});
// ok

@betula
Copy link
Member Author

betula commented Jun 7, 2021

low: proposal flow async and error with unhandled flow unsub

const a = value(0);

const b = value(0);
const c = value(0);

// For a first error on next cases
a.flow.async(async (a) => {
  const data = b.flow(() => {}).val; // Error here, necessary for using isolate here
}};


// Flow async proposal

const s = a.flow.async(async (a) => {
  if (!a) return stoppable.stop();

  return await load_subscriptions();
});

s.val // subscriptions or undefined
s.initialized.val
s.error.val
s.pending()

a.flow.async.debounce(300)
  .pipe(
    customDebounce, 
    async (a) => {
      if (!a) return stoppable.stop();
      const m = c.val; // Subscrible to m or not??
      return await load_subscriptions(m);
    }
  ); // readonly async flow

const all_ok = value.combine(a, s.initialized).select(([a, s]) => a && s)  // or value.combine([a, s.initialized])

// Rename pool to asyncs)))

// Constructors

value.async(async (v) => {});
signal.async(async (v) => {});

a.flow.async(async (a) => {});

const m = a.flow.async(async (a) => {}).single();

const h = a.sub.async(reactionable, async (state, val) => {}); // h.pending.val

const h_2 = pool(async (a,b,c,d,e) => {
  stoppable.stop();
});


// Syntax possibilities

a.async
   .debounce(300)
  .pipe(
    customDebounce, 
    async (a) => {
      if (!a) return stoppable.stop();
      const m = c.val; // Subscrible to m or not?? (untrack inside pipe section... hmmmm)
      return await load_subscriptions(m);
    }
  )
  .flow(async (a) => {
    return await load(a, b.val, c.val); // Depend on change any of that values
   })
; // readonly async flow

// Pipe <> Flow same words for not obvious differences... hmm

const s = flow.async(async () => {
  return await load(a.val, b.val, c.val);
});
// Syntax possibilities

const t = a.async
   .debounce(300)
  .flow.untrack(
    customDebounce, 
    async (a) => {
      if (!a) return stoppable.stop();
      const m = c.val;                                       // not subscribe to c
      return await load_subscriptions(m);
    }
  )
  .flow(async (a) => {
    return await load(a, b.val, c.val);              // subscribe to b and c
   })
; // readonly async flow

t.val 
t.ready.val
t.error.val
t.pending.val

// flow factory (only track, untrack unsupported)
const s = flow.async(async () => {
  return await load(a.val, b.val, c.val);
});
const f_sync = flow(() => {
  return sync_load(a.val, b.val, c.val);
});

// And pool

const p = pool(async (a,b,c,d,e) => {
  stoppable.stop();
});

p.pending.val

@betula
Copy link
Member Author

betula commented Jun 7, 2021

low: proposal pool syntax

const a = pool(async () => {});

a.single()
a.debounce(300)
a.throttle()

// or

a.pipe.single()
a.pipe.debounce(300)

a.pipe( ... ) // what is It?

and for values and signals

const a = value(0);

a.pool.debounce(100) // what is it?

@betula
Copy link
Member Author

betula commented Jun 8, 2021

low: on((stop) => {}, () => {}) implement

@betula
Copy link
Member Author

betula commented Jun 8, 2021

low: try deprecate stopppable

selector(init_value?, (stop) => {});
selector((stop?) => {});

cycle((stop) => {});
on((stop) => {}, () => {});




// But I think pool no need to use "(stop) =>" syntax, maybe stoppable() is better for pool?
// pool.stop

pool(async () => {
  const stop = pool.stop;
  pool.stop();
  pool.stop.throw();
});

pool.stoppable((stop) => {
  return async () => {

  }
});

@betula
Copy link
Member Author

betula commented Jun 8, 2021

low: signal.trigger.from method

Should be added:
signal.trigger.from
signal.trigger.flag.from

@betula
Copy link
Member Author

betula commented Jun 8, 2021

(Declined) proposal: signal.flag and value.flag

const flag = signal(false).pre((v) => !!v);

@betula
Copy link
Member Author

betula commented Jun 8, 2021

ver very low: proposal proxy property
const v = value({});
v.proxy.a = 10;
v.update.proxy(p => { // one transaction
  p.b = (p.a += 15);
});

@betula
Copy link
Member Author

betula commented Jun 8, 2021

proposal: name for production ready version "Universal data-flow"

@betula
Copy link
Member Author

betula commented Jun 8, 2021

low: think about "in one transaction" feature
const s = signal();
const v = value();

on(s, (s_v) => v.val += s_v);
on(() => [s,v], console.log);


on.transaction(s, (s_v) => v.val += s_v); // used one transaction with changed s

// Think about

@betula
Copy link
Member Author

betula commented Jun 8, 2021

proposal: queue implementation

const q = queue<Type?>(init?: Type[]);

// q(10); // Think about queue - is a reactive value with set of elements or is the signal for add next one... Hmm.

// q.queue // []

q.front // top
q.back // last element
// q.all // array of elements in queue
q.size
q.clear()

//

q.val
q.first: Value
q.last: Value
q.size: Value
q.active: Value
q.clear()

// Support queue for q.wrap and q.view // think about api
// val: <array_of_elements> readonly
// q(<new_element>)

Or q() - no possible, but 

q.add(value: Type)
q.val: Type
q.first: Value
q.last: Value
q.size: Value
q.active: Value
q.clear()

// How I can make queue with limited size same as in my swipe impl?

q = queue();

q(values: Type[]);
q.set(values: Type[]);
q.update(...);
q.val: Type;

q.add(value: Type);

q.first: Value
q.last: Value
q.size: Value
q.active: Value
q.empty: Value
q.clear()


//

const t = q.first

t.val: Type
t.started: Value
t.start();
t.release(); // remove item from queue (or dequeue)

// or

t.val: Type
t.start: ready(false).to(true)
t.remove(); // remove item from queue // or ready(false).to(true) too

Decorating add signal

const q = queue<Type>([], (queue, value: Type) => {
  const excluded = queue.slice(3);
  // const data = queue..
  // How to convert value to queue element?
});

const q = queue<Type>();
q.before (Signal)

q.before((value) => {
  stoppable.stop();
  transaction
  check q
  remove unnecessary q elems
  add new
  finish transaction
});

@betula
Copy link
Member Author

betula commented Jun 8, 2021

proposal: interceptor method

const a = value(5);
const b = value(1);

const unsub = a.interceptor((new_value, current_value, stop?) => {
  if (new_value == 1) {
    b.set(10);
    stop();
    return;
  }
  return current_value + new_value;
});
// stoppable supported

a(1); // b.val === 10, a.val === 5
a(2); // a.val === 7

Think about syntax for sub interceptions

const v = value(0);
const s = signal(0);
v.sub.intercept(s, (v_value, new_signal_value, stop ) => {
  ///
});
v.intercept.sub // alias

// or
v.sub.intercept(s, (v_value, new_signal_value, prev_signal_value ) => {
  stoppable.stop();
});
v.intercept.sub // alias

@betula
Copy link
Member Author

betula commented Jun 8, 2021

proposal: pool async oparators

pool.single(async ({ cancelled }) => {
  const zip = await search();
  if (cancelled()) return;
  return await unpack(zip);
});

// If exists active promise each query return It

// pool.throttle(150, async ({ cancelled, abortController?.., cancel }) => {
pool.throttle(150, async ({ stopped, abortController?.., stop }) => {
  const zip = await search();
  if (zip === 0) stop();
  if (stopped()) return;
  return await unpack(zip);
});

pool.debounce(150, async function * ({ cancel }) {
  const zip = yield search();
  if (zip === 0) cancel();
  return yield unpack(zip);
});

It is offtopic, but I want to think about throttle and debounce for signals:

const start = signal();
const delayedStart = signal.throttle(150, start);

const a = value();
const delayedA = value.throttle(150, a);

const p = pool(async () => await search());
const delayedP = pool.throttle(150, p);

Maybe only one throttle function for all necessaries.

@betula
Copy link
Member Author

betula commented Jun 8, 2021

low: external package realar-form

@betula
Copy link
Member Author

betula commented Jun 8, 2021

very low: add jsx method
const a = value(0);

return (
  <p>{a.jsx}</p>
)

return (
  <p>{a.jsx(v => v.map((i, k) => <i key={k}>{i}</i>))}</p>
)

😉

a.jsx
a.jsx.if
a.jsx.else
a.jsx.ifelse
a.jsx.map

// or

jsx(a)
jsx.if(a)
jsx.map(a)
// etc..

For making super performant interfaces 👍

@betula
Copy link
Member Author

betula commented Jun 8, 2021

very low: state machine impl

This abstraction is necessary for the implementation of serial operations. Reactions on each section of the serial operations.

const m = machine()
  .step(a, () => {})
  .step(b, () => 0)
  .step(machine.oneOf()
    .select(a, () => {})
    .select(b)
    .select(c), () => {})
  .loop();

But I think the yield generator function is an interesting way of decision.

loop(function *() {
  yield a;
  yield b;
  yield loop.oneOf([a, b, c]) // or loop.oneOf().select(a, () => {}).select(b, () => {})... chain function
  yield loop.race([a, b, c])
  yield loop.all([a, b, c])

  // Promise namespace operations for suggest
});

@betula
Copy link
Member Author

betula commented Jun 8, 2021

low: readonly method

const v = value(0);
const readonly_v = v.readonly();

@betula
Copy link
Member Author

betula commented Jun 9, 2021

Should research about argument passing to "prop" decorator, for the easy binding reactive container to class property:

class A {
  @prop(this.store) flat_store
}

@betula
Copy link
Member Author

betula commented Jun 9, 2021

proposal: value.extract

It should be extract object or array of reactive containers to object or array of usual javascript values.

const email = value('a@x');
const values = value.extract({ email });
console.log(values.email) // a@x.com

Possible kinds of name: "values" consistent with useValues

@betula
Copy link
Member Author

betula commented Jun 10, 2021

proposal: input as exportable api function

input.handler <- (ev) => ev.target.value
// proposal for another names.
// input.delegate
// input.change
// input.event

input.valid
input.valid.pending

input.validator(
  signal<string>().map((state) => /a/.test(state))
)
// input.validator.async() // or

// Interested but no consistency to other code base.
// input.validator((signal) => {
//   return signal.as.chan().map(async () => {})
// });

// Final perfect version
input.validator([
  signal<string>().filter() <-- what will happens if validator will be stopped
  chan<string>().map(async (state) => await fetch_is_valid(state)),
  (state) => /aa/.test(state),
  async (state) => await ext_test(state)
]);

proposal: remove select.multiple

Improve "select" to "select.multiple" signature

const s = select({ a: (state) => state.a });

The argument can be function, reactive container, object map, or array tuple.

proposal: reactive container as argument of "map" (and array of)

const pipe_double = signal<number>().map(state => state * 2);

value(1).map(pipe_double).val // 2
value(1).map([pipe_double, pipe_double]).val // 4

// Use signature as an array or as reactive container, or usual function signature.

@betula
Copy link
Member Author

betula commented Jun 11, 2021

low: test ts typings

https://github.com/reduxjs/reselect/blob/master/typescript_test/test.ts#L479

 // typings:expect-error     
 const baz2: string = baz;

@betula
Copy link
Member Author

betula commented Jun 12, 2021

fix: update component warn from modification in the render function

https://codesandbox.io/s/realar-api-unsubscribe-scopes-control-0sziu?file=/src/App.tsx

Warning: Cannot update a component (`fn`) while rendering a different component (`Form`). To locate the bad setState() call inside `Form`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render
    at Form (https://0sziu.csb.app/src/App.tsx:30:35)
    at fn (https://0sziu.csb.app/node_modules/realar/build/index.js:697:30)

@betula
Copy link
Member Author

betula commented Jun 12, 2021

brainstorm: signals two directional synchronization

const a = signal<number>();
const b = signal<number>();

sync(a, b);
sync(b, a);

Signals connection without the infinity loop error

I should realize a way to the bi-directional connection between signals.

const a = signal(0);
const b = signal(0);

sync.bi(a, b);
a.val++
b.val++
assert(a.val === 2)

@betula
Copy link
Member Author

betula commented Jun 18, 2021

signal.from.select broken ts types with tuples

signal
  .from(() => {
    return [
      buyAnnualLocale.val,
      sharedPurchases().annual_subscription.val
    ]
  })
  .select(([locale, sub]) => { // both variables have one type "string | Subscription | undefined"
    if (!sub) return void 0;
    const localized_price = (sub as any)?.localizedPrice;
    if (!localized_price) return void 0;
    
    return locale.text
  })

@betula
Copy link
Member Author

betula commented Jun 23, 2021

value(false) broken types for ts <4

const y: Value<boolean> = value(false);
/*
Type 'Value<false, false>' is not assignable to type 'Value<boolean, boolean>'.
  Type 'Value<false, false>' is not assignable to type '{ (value: boolean): void; set(value: boolean): void; }'.
    Types of parameters 'value' and 'value' are incompatible.
      Type 'boolean' is not assignable to type 'false'.ts(2322)
*/

@betula
Copy link
Member Author

betula commented Jun 23, 2021

proposal: manual rerun cycle outside

const h = cycle(() => {});
h.stop();
h.run();

@betula
Copy link
Member Author

betula commented Jun 24, 2021

proposal: shortcut not

sharedEye().enabled
    .as.signal()
    .filter()
    .filter(isNext.map(flag => !flag)) // TODO: shortcut not isNext.not()

@betula
Copy link
Member Author

betula commented Jun 24, 2021

proposal: value with no initial parameter

export const swipeAnimDirection = value<undefined | 'up' | 'down'>();

@betula
Copy link
Member Author

betula commented Jun 24, 2021

proposal: typings improvement for filter

 value<void | number>()
    .as.signal()
    .filter() // Should remove undefined | null | void from Will signal type
    .to(onlyNumberSignal);

@betula
Copy link
Member Author

betula commented Jun 27, 2021

proposal: new Scope api

const MyLogic = (initial: string) => {}

const MyScope = scope(MyLogic)

const A = () => {
  const B = useJsx(() => {
    const logic = useScoped(MyLogic)

    /* proposal: use scope logic from local section
    useLocal(() => {
      const logic = scoped(MyLogic)  // Warning scope recreation
      const logic = scoped.current(MuLogic) // Think about
    });
    */
    return
  });
  return <MyScope initial={'hello'}><B>{children}</B></MyScope>
}

@betula
Copy link
Member Author

betula commented Jun 27, 2021

fix: callback of sync or to methods should be untracked ... hmm.. check it

loader_queue.sync(async queue => {
  // should be untracked here
})

@betula
Copy link
Member Author

betula commented Jun 27, 2021

fix: typings for select without parameter

  const toggle = value(false).pre((_, state) => !state);
  const enabled = toggle.select(); // Incorrect: ValueReadonly<unknown>

@betula
Copy link
Member Author

betula commented Nov 8, 2021

proposel: value.will

const t = value.will<number>();
expect(t.val).toBeUndefined();
t.map(n: number => n + 1);

@betula
Copy link
Member Author

betula commented Nov 15, 2021

proposal

const takeUser = value();
const takeAuth = value();
takeAuth.onChange(takeUser.andUpdate)
takeUser.andSet()
takeUser() - alias for takeUser.andGet

const start = signal();
start.get - doesn't allowed
start.fire(new_value)

takeUser.onChange(start.fire)

start.getValue() - returns value instance

isDirty, isUndefined, isTouched
All methods created only by demand.

start.flow
start.pre

takeUser.compose

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant