1.0.0-rc.1 • Published 1 year ago

reacting-squirrel v1.0.0-rc.1

Weekly downloads
383
License
MIT
Repository
github
Last release
1 year ago

Reacting Squirrel

Framework for creation of the React apps using Express and Socket.io. Sample app can be cloned from GitHub.

Requirements

  • The module needs to be able to write in the app directory (config.appDir). It creates the directory where are stored the frontend maps.
  • The module needs to be able to write in the css directory (config.cssDir). It creates one app style.
  • The frontend needs the possibility to work with websockets (connection upgrade in nginx).

Installation

npm install reacting-squirrel --save

Usage

Simple app

// ./index.js
import Server from 'reacting-squirrel/server';

const app = new Server();

app.get('/', 'home', 'Home');

app.start();

// ./app/home.js
import React from 'react';
import { Page } from 'reacting-squirrel';

export default class HomePage extends Page {
    
    render() {
        return (
            <div>
                <h1>Home</h1>
            </div>
        );
    }
}

This code will start simple app on the default port with one page which will be the home page.

App using websockets for load the user

// ./index.js
import Server from 'reacting-squirrel/server';

import UserSocket from './socket.user';

import UserStore from './user-store';

const app = new Server({
    auth: (session, next) => {
        UserStore.load(session.id, (err, user) => {
            if (err) {
                next(err);
                return;
            }
            session.setUser(user);
            next();
        });
    }
});

app.get('/', 'home', 'Home');

app.registerSocketClass(UserSocket);

app.start();

// ./socket.user.js
import { SocketClass } from 'reacting-squirrel/server';

export default class User extends SocketClass {

    load(socket, data, next) {
        next(null, this.getUser());
    }
}

// ./app/home.js
import React from 'react';
import { Page } from 'reacting-squirrel';

export default class HomePage extends Page {

    state = {
        user: null,
    };

    componentDidMount() {
        super.componentDidMount();
        this.request('user.load', (err, user) => {
            if (err) {
                alert(err.message);
                return;
            }
            this.setState({ user });
        });
    }
    
    render() {
        const { user } = this.state;
        return (
            <div>
                <h1>Home</h1>
                <h2>{user ? user.name : 'Loading...'}</h2>
            </div>
        );
    }
}

This code will start simple app on the default port. After the page load the user.load event is emitted and UserSocket class is trying to load the logged user and send it back to the page.

Core functions

Routes register

The routes are registered on the server-side. The module is using express based routes registering.

import Server from 'reacting-squirrel/server';

const app = new Server();

// On the route '/' will be rendered the content copmponent located in {config.appDir}/home with Home title.
app.get('/', 'home', 'Home');

app.start();

Socket events register

The socket events can be directly registered. It should be used for simple socket events which don't need authorization.

import Server from 'reacting-squirrel/server';

const app = new Server();

// Frontend app can emit 'test' with some data. The event's listener emits the data back.
app.registerSocketEvent('test', (socket, data, next) => next(null, data));

app.start();

Socket classes register

The socket classes can handle multiple socket events prefixed by the class name. After the registration of the socket class socket events are automatically registered to the server app.

// ./socket.user.js
import { SocketClass } from 'reacting-squirrel/server';

export default class User extends SocketClass {

    load(socket, data, next) {
        // sends the authorized user data after the 'user.load' socket request
        next(null, this.getUser());
    }
}

// ./index.js
import Server from 'reacting-squirrel/server';

import UserSocket from './socket.user';

import UserStore from './user-store';

const app = new Server({
    auth: (session, next) => {
        UserStore.load(session.id, (err, user) => {
            if (err) {
                next(err);
                return;
            }
            session.setUser(user);
            next();
        });
    }
});

// Registeres the socket class
app.registerSocketClass(UserSocket);

app.start();

Components register

The module can register custom components which are rendered in custom DOM element in the layout.

import Server from 'reacting-squirrel/server';

const app = new Server();

// Frontend app tries to render component located at {config.appDir}/test to the DOM element with id 'test'
app.registerComponent('test', 'test');

app.start();

RSConfig

RSConfig file can contain list of routes, list of components and the directory with the socket classes. By default the file rsconfig.json is searched in the process.cwd() directory. If the file doesn't exist nothing happens. The path to the file can by changed with config.rsConfig option.

// rsconfig.json
{
    "routes": [
        {
            "route": "/",
            "component": "home",
            "title": "Home",
            "requiredAuth": false,
            "method": "GET"
        }
    ],
    "components": [
        {
            "id": "test",
            "component": "test"
        }
    ],
	"socketClassDir": "./dist/network/socket",
	"errorPage": "error-page"
}

Texts

In the startup process, the res directory is created in app directory. In that directory is created default text file text.json. The content of the text file is used as default dictionary using texting-squirrel module.

Accessing text from the component

All components have getText method to access the text from the dictionary.

import { Component } from 'reacting-squirrel';

export default class CustomComponent extends Component {

    render() {
        return <h1>{this.getText('title')}</h1>;
    }
}

Using Text component

The module contains a text component to handle dictionary directly from the JSX code.

import { Component, Text } from 'reacting-squirrel';

export default class CustomComponent extends Component {

    render() {
        return <Text dictionaryKey="title" tag="h1" />
    }
}

Socket communication

The module is using socket.io as a default communication protocol. The payload is chunked (default 10kB per chunk) and sent to the server.

Uploading files (experimental)

File upload can be diffucult over websocket. Without chunks big files disconnects the socket because of the pingTimeout. The file is sent to the server in chunks and converted to buffer on the server side.

const file = 'get somehow a File instance';
Socket.emit('file.upload', undefined, { file }, (progress) => console.log(progress));

Limitations

The server limits the message size. If the size is bigger than allowed limit, the socket is disconnected. The module has 100MB cap for the message size.

Decorators (experimental)

SocketClass

Decorators are designed for the the SocketClass methods.

broadcast

Data returned in the method are broadcasted to the client side.

requireAuth

Before the method execution is checked the logged user in the session. If it's not the error is thrown.

notSocketMethod

The method is not registered as socket method and cannot be called from the client side.

SocketRequest

castResponse

The response is casted to defined types using runtime-type module.

Docs

Checkout the documentation here.

TODO

  • Text component as separate module
  • res directory out of app directory to use texts in the server side

Deprecated

https://trello.com/b/FepP7DPC/reacting-squirrel

1.0.0-rc.1

1 year ago

1.0.0-beta.34

2 years ago

1.0.0-beta.37

2 years ago

1.0.0-beta.35

2 years ago

1.0.0-beta.36

2 years ago

1.0.0-beta.33

2 years ago

1.0.0-beta.31

2 years ago

1.0.0-beta.32

2 years ago

1.0.0-beta.30

2 years ago

1.0.0-beta.22

2 years ago

1.0.0-beta.23

2 years ago

1.0.0-beta.28

2 years ago

1.0.0-beta.29

2 years ago

1.0.0-beta.26

2 years ago

1.0.0-beta.27

2 years ago

1.0.0-beta.24

2 years ago

1.0.0-beta.25

2 years ago

1.0.0-beta.21

3 years ago

1.0.0-beta.20

3 years ago

1.0.0-beta.19

3 years ago

1.0.0-beta.18

3 years ago

1.0.0-beta.17

3 years ago

1.0.0-beta.16

3 years ago

1.0.0-beta.15

3 years ago

0.17.4

3 years ago

1.0.0-beta.14

3 years ago

1.0.0-beta.13

3 years ago

1.0.0-beta.11

3 years ago

1.0.0-beta.12

3 years ago

1.0.0-beta.10

3 years ago

1.0.0-beta.9

3 years ago

1.0.0-beta.8

3 years ago

1.0.0-beta.7

3 years ago

1.0.0-beta.6

3 years ago

1.0.0-beta.5

3 years ago

1.0.0-beta.4

3 years ago

1.0.0-beta.3

3 years ago

1.0.0-beta.2

3 years ago

1.0.0-beta.1

3 years ago

1.0.0-beta.0

3 years ago

0.17.3

4 years ago

0.17.2

4 years ago

0.17.0

4 years ago

0.17.1

4 years ago

0.16.10

4 years ago

0.16.9

4 years ago

0.16.7

4 years ago

0.16.8

4 years ago

0.16.6

4 years ago

0.16.5

4 years ago

0.16.4

4 years ago

0.16.3

4 years ago

0.16.2

4 years ago

0.16.1

4 years ago

0.16.0

4 years ago

0.15.1

4 years ago

0.15.0

4 years ago

0.14.14

4 years ago

0.14.13

4 years ago

0.14.12

4 years ago

0.14.11

4 years ago

0.14.10

4 years ago

0.14.9

4 years ago

0.14.8

4 years ago

0.14.7

5 years ago

0.14.6

5 years ago

0.14.5

5 years ago

0.14.4

5 years ago

0.14.3

5 years ago

0.14.2

5 years ago

0.14.1

5 years ago

0.14.0

5 years ago

0.13.14

5 years ago

0.13.13

5 years ago

0.13.12

5 years ago

0.13.11

5 years ago

0.13.10

5 years ago

0.13.9

5 years ago

0.13.8

5 years ago

0.13.7

5 years ago

0.13.6

5 years ago

0.13.5

5 years ago

0.13.4

5 years ago

0.13.3

5 years ago

0.13.2

5 years ago

0.13.1

5 years ago

0.13.0

5 years ago

0.12.0

5 years ago

0.11.1

5 years ago

0.11.0

5 years ago

0.10.2

5 years ago

0.10.1

5 years ago

0.10.0

5 years ago

0.9.10

5 years ago

0.9.9

5 years ago

0.9.8

5 years ago

0.9.7

5 years ago

0.9.6

5 years ago

0.9.5

5 years ago

0.9.4

5 years ago

0.9.3

5 years ago

0.9.2

5 years ago

0.9.1

5 years ago

0.9.0

5 years ago

0.8.3

5 years ago

0.8.2

5 years ago

0.8.1

5 years ago

0.8.0

5 years ago

0.7.2

5 years ago

0.7.1

5 years ago

0.7.0

5 years ago

0.6.8

5 years ago

0.6.7

5 years ago

0.6.6

5 years ago

0.6.5

5 years ago

0.6.4

5 years ago

0.6.3

5 years ago

0.6.2

5 years ago

0.6.1

5 years ago

0.6.0

5 years ago

0.5.9

5 years ago

0.5.8

5 years ago

0.5.7

5 years ago

0.5.6

6 years ago

0.5.5

6 years ago

0.5.4

6 years ago

0.5.3

6 years ago

0.5.2

6 years ago

0.5.1

6 years ago

0.5.0

6 years ago

0.4.9

6 years ago

0.4.8

6 years ago

0.4.7

6 years ago

0.4.6

6 years ago

0.4.5

6 years ago

0.4.4

6 years ago

0.4.3

6 years ago

0.4.2

6 years ago

0.4.1

6 years ago

0.4.0

6 years ago

0.3.7

6 years ago

0.3.6

6 years ago

0.3.5

6 years ago

0.3.4

6 years ago

0.3.3

6 years ago

0.3.2

6 years ago

0.3.1

6 years ago

0.3.0

6 years ago

0.2.5

6 years ago

0.2.4

6 years ago

0.2.3

6 years ago

0.2.2

6 years ago

0.2.1

6 years ago

0.2.0

6 years ago

0.1.1

6 years ago

0.1.0

6 years ago