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

feature/support better deep state #16

Merged
merged 7 commits into from
Jan 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.2.3] - 2021-01-26
### Changed
- change the Bus' property allowCrossOriginScript's name to loadScriptByFetch
- support better deep state which use the operator [] to indicate the index of an array

## [0.2.2] - 2021-01-05
### Added
- new API: socket.existsState
- new API: socket.existState
- add umd bundle
## [0.2.1] - 2020-12-10
### Added
Expand Down
22 changes: 16 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# obvious.js
[![Coverage Status](https://coveralls.io/repos/github/ObviousJs/obvious-core/badge.svg?branch=master)](https://coveralls.io/github/ObviousJs/obvious-core?branch=master) [![release](https://img.shields.io/github/release/ObviousJs/obvious-core.svg)](https://github.com/ObviousJs/obvious-core/releases) [![lastCommit](https://img.shields.io/github/last-commit/ObviousJs/obvious-core)](https://github.com/ObviousJs/obvious-core/commits/master) [![](https://img.shields.io/badge/document-%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87-brightgreen)](https://github.com/ObviousJs/obvious-core/blob/master/README.zh.md)

Obvious is a progressive micro-front-end framework. In the micro-front-end architecture, Obvious focuses on solving the problem of orchestration and communication between micro frontend applications. It aims to help users quickly build a basic micro-front-end system and support deeper customization to achieve a complete and reliable micro-front-end architecture by providing easy-to-understand APIs and flexible middleware mechanisms.
Obvious is a progressive micro-front-end library. In the micro-front-end architecture, Obvious focuses on solving the problem of orchestration and communication between micro frontend applications. It aims to help users quickly build a basic micro-front-end system and support deeper customization to achieve a complete and reliable micro-front-end architecture by providing easy-to-understand APIs and flexible middleware mechanisms.

## Features
- Provide flexible and convenient communication capabilities based on global state, event broadcast, and event unicast
Expand All @@ -20,7 +20,6 @@ umd:
`<script src="https://unpkg.com/obvious-core@{version}/dist/index.umd.js"></script>`

## Quick Start
![](docs/_media/tutorial-target.gif)

In host enviroment, create a bus and declare the resource info
```js
Expand Down Expand Up @@ -57,7 +56,7 @@ bus.createApp('react-app')
.bootstrap(async (config) => {
socket.unicast('unicast-event');
socket.broadcast('broadcast-event');
socket.initState('some-state', true);
socket.initState('someState', true);
ReactDOM.render(<App />, document.querySelector(config.mountPoint));
});
```
Expand All @@ -80,7 +79,8 @@ bus.createApp('vue-app')
socket.onBroadcast('broadcast-event', () => {
// do something
});
socket.watchState('some-state', () => {
socket.setState('someState.sub.prop.array', [])
socket.watchState('someState.sub.prop.array[0]', (val) => {
// do something
});
new Vue({
Expand All @@ -91,8 +91,18 @@ bus.createApp('vue-app')

In host enviroment, activate the application
```js
bus.activateApp('react-app', {mountPoint: '#react-app'});
bus.activateApp('vue-app', {mountPoint: '#vue-app'});
bus.activateApp('react-app', {mountPoint: document.getElementById('#react-app')});
bus.activateApp('vue-app', {mountPoint: document.getElementById('#vue-app')});
```

## Example
![](docs/_media/tutorial-target.gif)

```
npm run demo:install
npm run demo:react
npm run demo:vue
npm run demo:host
```

## Document
Expand Down
22 changes: 15 additions & 7 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ umd:
`<script src="https://unpkg.com/obvious-core@{version}/dist/index.umd.js"></script>`

## 快速开始
![](docs/_media/tutorial-target.gif)

在宿主环境中创建bus,并声明微应用资源
```js
import {createBus} from 'obvious-core';
Expand Down Expand Up @@ -57,7 +55,7 @@ bus.createApp('react-app')
.bootstrap(async (config) => {
socket.unicast('unicast-event');
socket.broadcast('broadcast-event');
socket.initState('some-state', true);
socket.initState('someState', true);
ReactDOM.render(<App />, document.querySelector(config.mountPoint));
});
```
Expand All @@ -80,7 +78,8 @@ bus.createApp('vue-app')
socket.onBroadcast('broadcast-event', () => {
// do something
});
socket.watchState('some-state', () => {
socket.setState('someState.sub.prop.array', [])
socket.watchState('someState.sub.prop.array[0]', (val) => {
// do something
});
new Vue({
Expand All @@ -91,12 +90,21 @@ bus.createApp('vue-app')

在宿主环境中,通过bus激活微应用
```js
bus.activateApp('react-app', {mountPoint: '#react-app'});
bus.activateApp('vue-app', {mountPoint: '#vue-app'});
bus.activateApp('react-app', {mountPoint: document.getElementById('#react-app')});
bus.activateApp('vue-app', {mountPoint: document.getElementById('#vue-app')});
```

## 文档
## 样例
![](docs/_media/tutorial-target.gif)

```
npm run demo:install
npm run demo:react
npm run demo:vue
npm run demo:host
```

## 文档
[obvious.js: 渐进式微前端库](https://obviousjs.github.io/obvious-core/#/)

## License
Expand Down
115 changes: 76 additions & 39 deletions dist/index.es.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,16 +141,49 @@ var getMappedState = function (state) {
});
return JSON.parse(JSON.stringify(mappedState));
};
var getStateName = function (stateNameLink) {
var result = '';
stateNameLink.forEach(function (item, index) {
var nextStateName = stateNameLink[index + 1];
var isNextObject = (typeof nextStateName) === 'string';
if (typeof item === 'number') {
result += (isNextObject ? "[" + item + "]." : "[" + item + "]");
}
else {
result += (isNextObject ? item + "." : item);
}
});
return result;
};
var getStateNameLink = function (stateName) {
var tempLink = stateName.split('.');
var resultLink = [];
tempLink.forEach(function (item) {
var arrayPattern = /(.+)\[(\d+)\]$/;
var matchedResult = arrayPattern.exec(item);
if (matchedResult !== null) {
var arrayName = matchedResult[1];
var arrayIndex = matchedResult[2];
getStateNameLink(arrayName).forEach(function (item) {
resultLink.push(item);
});
resultLink.push(Number(arrayIndex));
}
else {
resultLink.push(item);
}
});
return resultLink;
};
var get = function (rootState, stateLink) {
var current = rootState;
for (var _i = 0, stateLink_1 = stateLink; _i < stateLink_1.length; _i++) {
var key = stateLink_1[_i];
if (Array.isArray(current)) {
var index = Number(key);
if (isNaN(index)) {
if (typeof key !== 'number') {
return undefined;
}
current = current[index];
current = current[key];
}
else if (isObject(current)) {
current = current[key];
Expand All @@ -161,20 +194,19 @@ var get = function (rootState, stateLink) {
}
return current;
};
var set = function (rootStateName, rootState, stateLink, value) {
var set = function (rootStateName, rootState, subStateLink, value) {
var current = rootState;
for (var i = 0; i < stateLink.length; i++) {
var key = stateLink[i];
var index = Number(key);
if (i === stateLink.length - 1) {
for (var i = 0; i < subStateLink.length; i++) {
var key = subStateLink[i];
if (i === subStateLink.length - 1) { // traverse to the last
if (Array.isArray(current)) {
if (isNaN(index)) {
var stateName = rootStateName + "." + stateLink.slice(0, i).join('.');
if (typeof key !== 'number') {
var stateName = getStateName(__spreadArrays([rootStateName], subStateLink.slice(0, i)));
console.error(Errors.regardArrayAsObject(stateName, key));
return false;
}
else {
current[index] = value;
current[key] = value;
}
}
else {
Expand All @@ -184,23 +216,24 @@ var set = function (rootStateName, rootState, stateLink, value) {
else {
var next = null;
if (Array.isArray(current)) {
if (!isNaN(index)) {
next = index;
}
else {
var stateName = rootStateName + "." + stateLink.slice(0, i).join('.');
if (typeof key !== 'number') {
var stateName = getStateName(__spreadArrays([rootStateName], subStateLink.slice(0, i)));
console.error(Errors.regardArrayAsObject(stateName, key));
return false;
}
else {
next = key;
}
}
else {
next = key;
}
if (current[next] === undefined || current[next] === null) {
current[next] = {};
var nextNext = subStateLink[i + 1];
current[next] = (typeof nextNext === 'number') ? [] : {};
}
else if (!(Array.isArray(current[next]) || isObject(current[next]))) {
var stateName = rootStateName + "." + stateLink.slice(0, i + 1).join('.');
var stateName = getStateName(__spreadArrays([rootStateName], subStateLink.slice(0, i + 1)));
var type = typeof current[next];
console.error(Errors.regardBasicTypeAsObject(stateName, type));
return false;
Expand Down Expand Up @@ -383,7 +416,9 @@ var Socket = /** @class */ (function () {
* @param stateName
*/
Socket.prototype.existState = function (stateName) {
return this._state[stateName] !== undefined;
var stateNameLink = getStateNameLink(stateName);
var rootStateName = stateNameLink[0];
return this._state[rootStateName] !== undefined;
};
/**
* init a state
Expand Down Expand Up @@ -413,7 +448,7 @@ var Socket = /** @class */ (function () {
*/
Socket.prototype.getState = function (stateName) {
var mappedState = getMappedState(this._state);
return get(mappedState, stateName.split('.'));
return get(mappedState, getStateNameLink(stateName));
};
/**
* set the value of the state
Expand All @@ -422,8 +457,8 @@ var Socket = /** @class */ (function () {
*/
Socket.prototype.setState = function (stateName, arg) {
var _this = this;
var stateLink = stateName.split('.');
var rootStateName = stateLink[0];
var stateNameLink = getStateNameLink(stateName);
var rootStateName = stateNameLink[0];
if (this._state[rootStateName] === undefined) {
var msg = Errors.accessUninitializedState(rootStateName);
throw new Error(msg);
Expand All @@ -437,12 +472,12 @@ var Socket = /** @class */ (function () {
var isFunctionArg = typeof arg === 'function';
var oldValue = this.getState(stateName);
var newValue = isFunctionArg ? arg(oldValue) : arg;
if (stateLink.length === 1) {
if (stateNameLink.length === 1) {
this._state[rootStateName].value = newValue;
}
else {
var subStateLink = stateLink.slice(1);
var isSuccess = set(rootStateName, this._state[rootStateName].value, subStateLink, newValue);
var subStateNameLink = stateNameLink.slice(1);
var isSuccess = set(rootStateName, this._state[rootStateName].value, subStateNameLink, newValue);
if (!isSuccess) {
return;
}
Expand All @@ -451,7 +486,8 @@ var Socket = /** @class */ (function () {
var events = Object.keys(this.eventEmitter.getBroadcastEvents());
var resolvedStates = getResolvedStates(stateName, events);
resolvedStates.forEach(function (name) {
_this.broadcast("$state-" + name + "-change", get(newState, name.split('.')), get(oldState, name.split('.')));
var notifiedStateNameLink = getStateNameLink(name);
_this.broadcast("$state-" + name + "-change", get(newState, notifiedStateNameLink), get(oldState, notifiedStateNameLink));
});
};
/**
Expand All @@ -460,8 +496,8 @@ var Socket = /** @class */ (function () {
* @param callback
*/
Socket.prototype.watchState = function (stateName, callback) {
var stateLink = stateName.split('.');
var rootStateName = stateLink[0];
var stateNameLink = getStateNameLink(stateName);
var rootStateName = stateNameLink[0];
if (this._state[rootStateName] === undefined) {
var msg = Errors.accessUninitializedState(rootStateName);
throw new Error(msg);
Expand All @@ -474,9 +510,7 @@ var Socket = /** @class */ (function () {
* @param callback
*/
Socket.prototype.unwatchState = function (stateName, callback) {
var stateLink = stateName.split('.');
var rootStateName = stateLink[0];
if (this._state[rootStateName] === undefined) {
if (!this.existState(stateName)) {
throw new Error(Errors.accessUninitializedState(stateName));
}
this.eventEmitter.removeBroadcastEventListener("$state-" + stateName + "-change", callback);
Expand All @@ -489,9 +523,12 @@ var Socket = /** @class */ (function () {
Socket.prototype.waitState = function (dependencies, timeout) {
var _this = this;
if (timeout === void 0) { timeout = 10 * 1000; }
// remove all ready states first
dependencies = dependencies.filter(function (stateName) {
return _this._state[stateName] === undefined;
dependencies = dependencies.map(function (stateName) {
var stateNameLink = getStateNameLink(stateName);
var rootStateName = stateNameLink[0];
return rootStateName;
}).filter(function (rootStateName) {
return _this._state[rootStateName] === undefined;
});
if (dependencies.length === 0) {
return Promise.resolve(getMappedState(this._state));
Expand All @@ -503,8 +540,8 @@ var Socket = /** @class */ (function () {
var msg = Errors.waitStateTimeout(dependencies);
reject(new Error(msg));
}, timeout);
var stateInitialCallback = function (stateName) {
var index = dependencies.indexOf(stateName);
var stateInitialCallback = function (rootStateName) {
var index = dependencies.indexOf(rootStateName);
if (index !== -1) {
dependencies.splice(index, 1);
}
Expand Down Expand Up @@ -620,7 +657,7 @@ var Bus = /** @class */ (function () {
this._state = {};
this.apps = {};
this.dependencyDepth = 0;
this.allowCrossOriginScript = true;
this.loadScriptByFetch = false;
this.maxDependencyDepth = 100;
/**
* define fetchJs、loadJs and loadCss as arrow function because
Expand Down Expand Up @@ -705,7 +742,7 @@ var Bus = /** @class */ (function () {
if (!(_i < _a.length)) return [3 /*break*/, 8];
asset = _a[_i];
if (!/^.+\.js$/.test(asset)) return [3 /*break*/, 6];
if (!this.allowCrossOriginScript) return [3 /*break*/, 3];
if (!!this.loadScriptByFetch) return [3 /*break*/, 3];
return [4 /*yield*/, this.loadJs(asset)];
case 2:
_b.sent();
Expand Down Expand Up @@ -768,7 +805,7 @@ var Bus = /** @class */ (function () {
return [3 /*break*/, 5];
case 2:
if (!((_a = this.middleware) === null || _a === void 0 ? void 0 : _a.handleLoad)) return [3 /*break*/, 4];
return [4 /*yield*/, ((_b = this.middleware) === null || _b === void 0 ? void 0 : _b.handleLoad(name, this.allowCrossOriginScript ? this.loadJs : this.fetchJs, this.loadCss))];
return [4 /*yield*/, ((_b = this.middleware) === null || _b === void 0 ? void 0 : _b.handleLoad(name, this.loadScriptByFetch ? this.fetchJs : this.loadJs, this.loadCss))];
case 3:
_c.sent();
return [3 /*break*/, 5];
Expand Down
Loading