Almin

Almin

  • Docs
  • API
  • Blog
  • Help
  • GitHub

›Recent Posts

Recent Posts

  • Almin v0.18 – React Native compatible
  • Almin v0.17 – Support `context.useCase#execute` typing and new React Context
  • New Website

Almin v0.18 – React Native compatible

August 27, 2018

azu

almin@0.18.0 is released 🎉

Summary

  • Deprecate context.useCase#executor
    • Use context.useCase#execute instead of it
    • almin/migration-tools help to migrate it
  • Work almin in React Native without installing events module
    • Drop to use events of Node.js Core API

🥇 Migration

almin-migration-tools support migration from 0.17.x to 0.18.x.

npx @almin/migration-tools

This(0.17.x → 0.18.x) migration also supports TypeScript.

npx @almin/migration-tools "src/**/*.{ts,tsx}"
  • almin/migration-tools: Migration scripts for Almin.

🔥 Breaking Change

TypeScript user:

If you use Almin with TypeScript, please upgrade to TypeScript 3.0. Almin 0.18 require TypeScript 3.0.

If you seen following compile error, you should upgrade to TypeScript 3.0.

Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<{ state: StateMap<{ subscriptionList: any; subscri...'.
  Type '{}' is not assignable to type 'Readonly<Pick<StateMap<{ subscriptionList: any; subscriptionContents: any; appHeader: any; appPre...'.

JavaScript user:

No breaking change.

⭐ Features

Make execute type complete #355 #107

For TypeScript user

UseCaseExecutor#executor has been introduced as a workaround for TypeScript #107.

In Almin 0.18+, UseCaseExecutor#execute work with TypeScript #355

📝 Require TypeScript 3.0+

So, you should use UseCaseExecutor#execute instead of UseCaseExecutor#executor.

Before: executor()

import { UseCase, Context } from "almin";
class MyUseCaseA extends UseCase {
    execute(_a: string) {}
}
const context = new Context({
    store: createStore({ name: "test" })
});

// executor
context.useCase(new MyUseCaseA()).executor(useCase => useCase.execute("A")); 

After: execute()

import { UseCase, Context } from "almin";
class MyUseCaseA extends UseCase {
    execute(_a: string) {}
}
const context = new Context({
    store: createStore({ name: "test" })
});

//execute
context.useCase(new MyUseCaseA()).execute("A");

These are same meaning without syntax.

Deprecate executor() #356

You can migrate from executor to execute by migration tools

npx @almin/migration-tools "src/**/*.{js,ts,tsx}" --script "executor-to-execute"
  • almin/migration-tools: Migration scripts for Almin.

♻️ Refactoring

Drop to use events module #352

Almin 0.18 drop to use Node.js's events module.

Previously, Almin use events module of Node.js Core API. The events module is polyfill-ed by bundler like webpack or browserify. But, React Native's bundler does not bundle it.

As a result, almin 0.18 improves to

  • support React Native compatible
  • reduce file size

We will work on Almin 1.0.0 within a few month. I(@azu) think that last blocker of 1.0.0 is Store design.

  • Almin: Store#receivePayload design · Issue #312 · almin/almin

Also, We welcome to your contribution. If you want to contribute to almin, please check good first issue.

Almin v0.17 – Support `context.useCase#execute` typing and new React Context

June 9, 2018

azu

almin@0.17.0 is released 🎉

🔥 Breaking Change

Make Payload abstract class completely

You can not call super({ type: "type" }) in subclas of Payload anymore. Payload does not accept arguments.

New Payload is an abstract class.

export abstract class Payload<T = any> {
    /**
     * `type` is unique property of the payload.
     * A `type` property which may not be `undefined`
     * It is a good idea to use string constants or Symbol for payload types.
     */
    abstract readonly type: T;
}

This changes is related for TypeScript users.

⭐ Feature

Support context.useCase#execute typing #342 #107

We already have context.useCase(someUseCase).executor(useCase => useCase.execute()) for TypeScript. It is a alternative syntax of context.useCase(someUseCase).execute(), but it is type-safe method.

Previously, Almin can not expected args type of context.useCase(someUseCase).execute(args).

Almin 0.17 will expect args type of context.useCase(someUseCase).execute(args).

Examples: Almin 0.17+

import { UseCase, Context } from "almin";
class MyUseCaseA extends UseCase {
    execute(_a: string) {}
}
const context = new Context({
    store: createStore({ name: "test" })
});

// valid
context.useCase(new MyUseCaseA()).execute("A");
// invalid
context.useCase(new MyUseCaseA()).execute(); // no argument
context.useCase(new MyUseCaseA()).execute(1); // can not pass number
context.useCase(new MyUseCaseA()).execute(1, 2); // can not pass number

📝Drawback of execute()

However, execute() method has a drawback. Following case is not error in Almin 0.17.

import { UseCase, Context } from "almin";
class MyUseCaseA extends UseCase {
    execute(_a: string) {}
}
const context = new Context({
    store: createStore({ name: "test" })
});
// **valid in almin 0.17**
context.useCase(new MyUseCaseA()).execute("A". 42);

For more details, see https://github.com/almin/almin/issues/107#issuecomment-384993458

♻ Improving

use assertOK instead of assert module #341

Reduce file size of almin pacakge.

Before

Package size: 12.55 KB

After

Package size: 8.27 KB

⬇️ 4kb

Related Issue:

  • Drop to use events · Issue #352 · almin/almin

🆕 New Modules

@almin/react-context #346 #112

@almin/react-context provide React Context wrapper for almin. It is based on new React Context API.

It has same feature with almin-react-container, but different interface.

import { Context, StoreGroup } from "almin";
import { createStore } from "@almin/store-test-helper";
import { createReactContext } from "@almin/react-context";
// Create Almin context
const context = new Context({
    // StoreGroup has {a, b, c} state
    store: new StoreGroup({
        // createStore is a test helper that create Store instance of Almin
        // initial state of `a` is { value: "a" }
        a: createStore({ value: "a" }),
        b: createStore({ value: "b" }),
        c: createStore({ value: "c" }),
    })
});
// Create React Context that wrap Almin Context
const { Consumer, Provider } = createReactContext(context);
// Use Provider
class App extends React.Component {
    render() {
        return (
            // You should wrap Consumer with Provider
            <Provider>
                {/* Consumer children props is called when Almin's context is changed */}
                <Consumer>
                    {state => {
                        return <ul>
                            <li>{state.a.value}</li>;
                            <li>{state.b.value}</li>;
                            <li>{state.c.value}</li>;
                        </ul>
                    }}
                </Consumer>
            </Provider>
        );
    }
}

We want to provide a single React bining in the future. Because, two official way may confuse user.

Welcome feedback about @almin/react-context!

@almin/store-test-helper #347

@almin/store-test-helper provide factory function of Store for testing.

New Website

December 10, 2017

azu

Almin's website move from GitBook to Docusaurus.

Docusaurus optimize to maintain Open Source Documentation Websites.

Almin
Docs
Getting StartedTutorialAPI Reference
Community
User ShowcaseStack OverflowTwitter
GitHub
GitHubReleasesIssuesStar
Copyright © 2021 azu