mobx-state-tree-entity
Version:
React state management made for humans.
356 lines (336 loc) • 17.5 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("mobx-state-tree"), require("axios"));
else if(typeof define === 'function' && define.amd)
define(["mobx-state-tree", "axios"], factory);
else if(typeof exports === 'object')
exports["mobx-state-tree-entity"] = factory(require("mobx-state-tree"), require("axios"));
else
root["mobx-state-tree-entity"] = factory(root[undefined], root["axios"]);
})(window, function(__WEBPACK_EXTERNAL_MODULE__0__, __WEBPACK_EXTERNAL_MODULE__1__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 3);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__0__;
/***/ }),
/* 1 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__1__;
/***/ }),
/* 2 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
// CONCATENATED MODULE: ./.tmp/Status.js
var Status;
(function (Status) {
Status[Status["PENDING"] = 0] = "PENDING";
Status[Status["IN_PROGRESS"] = 1] = "IN_PROGRESS";
Status[Status["SUCCESS"] = 2] = "SUCCESS";
Status[Status["ERROR"] = 3] = "ERROR";
})(Status || (Status = {}));
// EXTERNAL MODULE: external {"commonjs2":"mobx-state-tree","commonjs":"mobx-state-tree","amd":"mobx-state-tree"}
var external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_ = __webpack_require__(0);
// EXTERNAL MODULE: external "axios"
var external_axios_ = __webpack_require__(1);
var external_axios_default = /*#__PURE__*/__webpack_require__.n(external_axios_);
// CONCATENATED MODULE: ./.tmp/useSingletonEntityl.js
var __assign = (undefined && undefined.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __generator = (undefined && undefined.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var metadata = external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"]
.model('Metadata', {
error: external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"].maybeNull(external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"].string),
isHydrating: external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"].optional(external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"].boolean, false),
isLoading: external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"].optional(external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"].boolean, false),
status: external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"].optional(external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"].integer, Status.PENDING)
})
.volatile(function () { return ({
hasHydrated: false
}); })
.views(function (self) { return ({
get isDirty() {
// ephemeral value doesn't match persisted one - model is dirty
var value = Object(external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["getParent"])(self).value;
var persistedValue = Object(external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["getParent"])(self).persistedValue;
return (persistedValue &&
value &&
JSON.stringify(value) !== JSON.stringify(persistedValue));
},
get hasError() {
return !!self.error;
}
}); });
var deriveTypeFromStateKey = function (value) {
switch (typeof value) {
case 'string':
return external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"].string;
case 'boolean':
return external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"].boolean;
case 'number':
return external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"].number;
case 'object':
if (Array.isArray(value)) {
// if the array is empty, we assume it is an array of strings
if (value.length === 0) {
return external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"].array(external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"].string);
}
else {
// else, we assume the type of items in the array matches the type of the array's first item
return external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"].array(deriveTypeFromStateKey(value[0]));
}
}
else {
// if this is a full object, we recursively derive an entity model from it
return deriveModelFromState(value);
}
break;
default:
throw new Error('state-to-mox-state-tree-types');
}
};
var deriveModelFromState = function (state) {
if (typeof state !== 'object' || Array.isArray(state)) {
throw new Error(''); // TODO: proper error msg
}
else {
var modelProps = {};
for (var _i = 0, _a = Object.keys(state); _i < _a.length; _i++) {
var key = _a[_i];
var value = state[key];
modelProps[key] = deriveTypeFromStateKey(value);
}
return external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"].model(modelProps).actions(function (self) { return ({
setValues: function (values) {
// compose the snapshot with existing properties so we can submit partial updates
var updateContent = __assign({}, self, values);
Object(external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["applySnapshot"])(self, updateContent);
}
}); });
}
};
var useSingletonEntity = function (initialValue, endpoint) {
var instanceType = deriveModelFromState(initialValue);
var apiEntityModel = external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"]
.model('', {
metadata: metadata,
persistedValue: external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"].optional(instanceType, initialValue),
value: external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"].optional(instanceType, initialValue)
})
.actions(function (self) { return ({
read: Object(external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["flow"])(function get(id) {
var url, response, e_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
self.metadata.isLoading = true;
self.metadata.isHydrating = !self.metadata.hasHydrated;
_a.label = 1;
case 1:
_a.trys.push([1, 3, 4, 5]);
self.metadata.status = Status.IN_PROGRESS;
url = id ? endpoint + '/' + id : endpoint;
return [4 /*yield*/, external_axios_default.a.get(url)];
case 2:
response = _a.sent();
Object(external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["applySnapshot"])(self.value, response.data);
Object(external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["applySnapshot"])(self.persistedValue, response.data);
self.metadata.status = Status.SUCCESS;
return [3 /*break*/, 5];
case 3:
e_1 = _a.sent();
self.metadata.error = JSON.stringify(e_1);
self.metadata.status = Status.ERROR;
return [3 /*break*/, 5];
case 4:
self.metadata.isLoading = false;
self.metadata.isHydrating = false;
self.metadata.hasHydrated = true;
return [7 /*endfinally*/];
case 5: return [2 /*return*/, self.persistedValue];
}
});
}),
update: Object(external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["flow"])(function update(id) {
var url, response, e_2;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
self.metadata.isLoading = true;
self.metadata.isHydrating = !self.metadata.hasHydrated;
_a.label = 1;
case 1:
_a.trys.push([1, 3, 4, 5]);
self.metadata.status = Status.IN_PROGRESS;
url = id ? endpoint + '/' + id : endpoint;
return [4 /*yield*/, external_axios_default.a.put(url, self.value)];
case 2:
response = _a.sent();
Object(external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["applySnapshot"])(self.persistedValue, response.data);
Object(external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["applySnapshot"])(self.value, response.data);
self.metadata.status = Status.SUCCESS;
return [3 /*break*/, 5];
case 3:
e_2 = _a.sent();
self.metadata.error = JSON.stringify(e_2);
self.metadata.status = Status.ERROR;
return [3 /*break*/, 5];
case 4:
self.metadata.isLoading = false;
self.metadata.isHydrating = false;
self.metadata.hasHydrated = true;
return [7 /*endfinally*/];
case 5: return [2 /*return*/, self.persistedValue];
}
});
})
}); });
var remoteEntity = function (entityInstance) { return external_commonjs2_mobx_state_tree_commonjs_mobx_state_tree_amd_mobx_state_tree_["types"].optional(entityInstance[0], entityInstance[1]); };
var devicesRemoteEntity = [
apiEntityModel,
{
metadata: {
error: null,
hasLoaded: false,
isDirty: false,
isHydrating: false,
isLoading: false,
status: Status.PENDING
},
value: initialValue
}
];
return remoteEntity(devicesRemoteEntity);
};
// CONCATENATED MODULE: ./.tmp/index.js
/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "Status", function() { return Status; });
/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "deriveModelFromState", function() { return deriveModelFromState; });
/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "useSingletonEntity", function() { return useSingletonEntity; });
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(2);
/***/ })
/******/ ]);
});