Code Monkey home page Code Monkey logo

remini's People

Contributors

betula avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

rajeshdish

remini's Issues

article: the best shared state pattern with remini

The central part of any complex application is stateful logic. Application has a state and a logic that uses and modifies the state.

For example, according to Redux architecture the one state, and logic inside sagas, thunks, reducers, or action creators.

Remini proposal (suppose) pattern combined great ideas from Redux, Vue, and Angular. In depends on your internal particularities, you can choose one of the supposed implementations. The first one will be better for Redux-familiar developers.

When the center of our stateful logic is the Store.

const User = () => {
  $state = box(initialState);

  const login = () => {
    update($state, state => { ...state, loggedIn: true });
  }

  const logout = () => {
    update($state, state => { ...state, loggedIn: false });
  }

  return Object.assign($state, {
    login,
    logout
  });
}

And the second one is the "flat style". All modules should be reactive transparently, looks like simple usual objects.

const User = () => {
  $name = box('Amelia');
  $loggedIn = box(false);

  const login = () => {
    put($loggedIn, true);
  }

  const logout = () => {
    put($loggedIn, false);
  }

  return {
    get name() {
      return val($name);
    },
    get logginIn() {
      return val($logginIn);
    },

    login,
    logout
  });
}

Proposal to change a box signature Or are method chains and classes already boring to everyone?

Discussion

Or what I suggest will only worsen the situation? Will make the bundle size bigger! And again it will create a bunch of painfully growing api!

My dear community, please help) I will be glad to hear your thoughts!

Cons of the current way:

  • Importing a separate function for each operation is can be inconvenient.
  • It is not convenient to use a function call for reading, writing, and updating operations.

Cons of the new way:

  • Everyone is tired of classes
  • Assignment via the "=" operator looks outdated
  • Looks complicated and hard to learn
const title = box(0);
title._ += 10;

expr(() => title._ + 10).to((val) => console.log(val));

title.to((p) => console.log(p));
title.map(v => v + 10);

const ev = event();
ev.to(k => console.log(k));
ev.filter().map().to();
ev.fire();

const evFire = ev.fire; 
evFire(); // I'm not sure, it looks like an unnecessary complication at the start. Maybe later.

const onDragFinish = event();
onDragFinish.fire();

onDragFinidsh.to(() => console.log('drag finished'));

const custom = expr(() => title._ + 10, (k) => title._ += k);
custom.to(onDragFinish);

custom._ += 10;
custom.write(20);
custom.read();
custom.update(v => v + 1)

custom.readonly()
ev.readonly()
//

useBox(title, /* [title] */); // deps unnecessary
useExpr(() => ({
    title: title._,
    custom: custom._,
    valu
}), [valu]);

// support only one argument in `to`, break support prev value.
// also should be removed unused API (sync, once, cycle)

improve idea: add shallow comparer

Should be very simple syntax:

on(() => shallow(read($b)), listener)
sync(() => shallow({ a: read($a).k.m, b: read($b).e.f }), $v); 
wrap
map($a, (a) => shallow(a))

// or

box.shallow
wrap.shallow
on.shallow
on.once.shallow
sync.shallow

useBox.shallow
useBoxes.shallow

This is a decorator for returns value.

renaming: rename "map" to "select"

const $user = box({
  name: 'Joe',
  email: '[email protected]',
  settings: {},
  avatar: 'https://avatar.com/1.jpg'
})

const $avatar = map($user, user => user.avatar)
// new version
const $avatar = select($user, user => user.avatar)

proposal: lazy initialization

The main reason: The decrease in result application bundle size.
If I can use lazy initialization, I can make isolated scopes and clear the state whole the app.

const b = box(0);
const n = wrap(() => get(b) + 1);

on(n, v => console.log('next', v);

// All of it should be lazy

I should deny of subscription to function expression, for example:

on(() => get(n), v => console.log('next', v)) // deny, no possible to make lazy subscription

After I can add the new function in a separate folder.

isolate(async () => {
  await runApp();
});

After remini can be used without dependency injections or providing service. Just standard modules!

minor: object spread operator using

const
  { sel, expr, box, untrack: _re_untrack, batch: _re_batch } = require('reactive-box'),

I should check it and understand browser support requirements.

docs: store pattern

// ./custom.store.ts

import { wrap, box, val } from "remini";

export const CustomStore = () => {
  const initialState = {
    address: {},
    user: {}
  };
  const $store = box(initialState);

  // example of performance optimization if store has a lot of often changes outside of "user" object
  const $user =  wrap(() => val($store).user);

  return Object.assign($store, {
    get user() {
      return val($user);
    },

    // this will be enought for most cases
    get address() {
      return val($store).address;
    },

    // ... some methods where
  })
}

And useful usage in everywhere in the code. React example:

// ./Custom.tsx

import { provide } from "provi";
import { useBox } from "remini/react";

const Custom = () => {
  const custom = useBox(provide(CustomStore));
  return (
    <>
      <b>{custom.user}</b>
      <address>{custom.address}</address>
    </>
  )
}

or without hooks:

// ./Custom.tsx

import { provide } from "provi";
import { component } from "remini";

const Custom = component(() => {
  const $custom = provide(Custom);
  return (
    <>
      <b>{$custom.user}</b>
      <address>{$custom.address}</address>
    </>
  )
})

brainstorm: api function when unsupported usage

    when(
      () => this.isDataCanBeLoaded,
      () => {
        this.load(this.rootStore.user.language);
      }
    );

This is synonym of

    on(
      () => this.isDataCanBeLoaded,
      (val) => {
        val && this.load(this.rootStore.user.language);
      }
    );

but not almost

const b = box(0)
when(b, console.log)

b(1) // output: 1
b(2) // nothing
b(3) // nothing
b(0) // nothing

b(2) // output: 2

Idea

Rename Remini "when" function to "wait", hmmm, think about

feat: rename event to trigger

import { box, event, val } from "remini";

export const LocaleConfig = () => {
  const $code = box('ru');

  const setLocaleTrigger = trigger();

  return {
    get code() {
      return val($code);
    }
  };
};

idea: automatically component wrapping

We should decorate the standard JSX h function:
(similar preact in ts config)

{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "preact",
  }
}

preparing release: 1.1

  • "on" used "listen" from "evemin" inside for events
  • Remove "on.once" if it will be neccessary in the future add it.
  • Add "when" function for deeply integration with javascript
  • Remove "un" function from exports
  • Type Box by default should be "readable" not "writable"

feat proposal: selector and shallow

box.shallow()
on.shallow()
once.shallow()
sync.shallow()
wrap.shallow()
promiseNext.shallow()

useBoxShallow()
useSelector()
useSelectorShallow()

const Comp = () => {
  const active = useSelector(homeRoute, state => state.active, [...deps])
}

api idea: useStateBox

const useStateBox = (fn)

const $user = useStateBox(() => {
  return {
    a, b, c
  }
}, [a, b, c]);

And It's will be interesting to combine it with the "local" module.

const logic = useLocal(() => new Logic(a,b, $user), [a, b, $user])

renaming idea: rename observe

observe should be observer.
For consistency with Mobx, for previously Mobx developers.

Reason:
observe - mean "to observe" it's an action. But decorator should be not an action.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.