949 lines
28 KiB
JavaScript
949 lines
28 KiB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
|
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
module.exports = factory();
|
|
else if(typeof define === 'function' && define.amd)
|
|
define([], factory);
|
|
else if(typeof exports === 'object')
|
|
exports["reduxLogger"] = factory();
|
|
else
|
|
root["reduxLogger"] = factory();
|
|
})(this, function() {
|
|
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] = {
|
|
/******/ exports: {},
|
|
/******/ id: moduleId,
|
|
/******/ loaded: false
|
|
/******/ };
|
|
|
|
/******/ // Execute the module function
|
|
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
|
|
/******/ // Flag the module as loaded
|
|
/******/ module.loaded = 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;
|
|
|
|
/******/ // __webpack_public_path__
|
|
/******/ __webpack_require__.p = "";
|
|
|
|
/******/ // Load entry module and return exports
|
|
/******/ return __webpack_require__(0);
|
|
/******/ })
|
|
/************************************************************************/
|
|
/******/ ([
|
|
/* 0 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
__webpack_require__(2);
|
|
module.exports = __webpack_require__(2);
|
|
|
|
|
|
/***/ },
|
|
/* 1 */
|
|
/***/ function(module, exports) {
|
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var repeat = exports.repeat = function repeat(str, times) {
|
|
return new Array(times + 1).join(str);
|
|
};
|
|
|
|
var pad = exports.pad = function pad(num, maxLength) {
|
|
return repeat("0", maxLength - num.toString().length) + num;
|
|
};
|
|
|
|
var formatTime = exports.formatTime = function formatTime(time) {
|
|
return pad(time.getHours(), 2) + ":" + pad(time.getMinutes(), 2) + ":" + pad(time.getSeconds(), 2) + "." + pad(time.getMilliseconds(), 3);
|
|
};
|
|
|
|
// Use performance API if it's available in order to get better precision
|
|
var timer = exports.timer = typeof performance !== "undefined" && performance !== null && typeof performance.now === "function" ? performance : Date;
|
|
|
|
/***/ },
|
|
/* 2 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.logger = exports.defaults = undefined;
|
|
|
|
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
|
|
|
var _core = __webpack_require__(3);
|
|
|
|
var _helpers = __webpack_require__(1);
|
|
|
|
var _defaults = __webpack_require__(4);
|
|
|
|
var _defaults2 = _interopRequireDefault(_defaults);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
/**
|
|
* Creates logger with following options
|
|
*
|
|
* @namespace
|
|
* @param {object} options - options for logger
|
|
* @param {string | function | object} options.level - console[level]
|
|
* @param {boolean} options.duration - print duration of each action?
|
|
* @param {boolean} options.timestamp - print timestamp with each action?
|
|
* @param {object} options.colors - custom colors
|
|
* @param {object} options.logger - implementation of the `console` API
|
|
* @param {boolean} options.logErrors - should errors in action execution be caught, logged, and re-thrown?
|
|
* @param {boolean} options.collapsed - is group collapsed?
|
|
* @param {boolean} options.predicate - condition which resolves logger behavior
|
|
* @param {function} options.stateTransformer - transform state before print
|
|
* @param {function} options.actionTransformer - transform action before print
|
|
* @param {function} options.errorTransformer - transform error before print
|
|
*
|
|
* @returns {function} logger middleware
|
|
*/
|
|
function createLogger() {
|
|
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
|
|
var loggerOptions = _extends({}, _defaults2.default, options);
|
|
|
|
var logger = loggerOptions.logger,
|
|
transformer = loggerOptions.transformer,
|
|
stateTransformer = loggerOptions.stateTransformer,
|
|
errorTransformer = loggerOptions.errorTransformer,
|
|
predicate = loggerOptions.predicate,
|
|
logErrors = loggerOptions.logErrors,
|
|
diffPredicate = loggerOptions.diffPredicate;
|
|
|
|
// Return if 'console' object is not defined
|
|
|
|
if (typeof logger === 'undefined') {
|
|
return function () {
|
|
return function (next) {
|
|
return function (action) {
|
|
return next(action);
|
|
};
|
|
};
|
|
};
|
|
}
|
|
|
|
if (transformer) {
|
|
console.error('Option \'transformer\' is deprecated, use \'stateTransformer\' instead!'); // eslint-disable-line no-console
|
|
}
|
|
|
|
// Detect if 'createLogger' was passed directly to 'applyMiddleware'.
|
|
if (options.getState && options.dispatch) {
|
|
// eslint-disable-next-line no-console
|
|
console.error('[redux-logger] redux-logger not installed. Make sure to pass logger instance as middleware:\n\n// Logger with default options\nimport { logger } from \'redux-logger\'\nconst store = createStore(\n reducer,\n applyMiddleware(logger)\n)\n\n\n// Or you can create your own logger with custom options http://bit.ly/redux-logger-options\nimport createLogger from \'redux-logger\'\n\nconst logger = createLogger({\n // ...options\n});\n\nconst store = createStore(\n reducer,\n applyMiddleware(logger)\n)\n');
|
|
|
|
return function () {
|
|
return function (next) {
|
|
return function (action) {
|
|
return next(action);
|
|
};
|
|
};
|
|
};
|
|
}
|
|
|
|
var logBuffer = [];
|
|
|
|
return function (_ref) {
|
|
var getState = _ref.getState;
|
|
return function (next) {
|
|
return function (action) {
|
|
// Exit early if predicate function returns 'false'
|
|
if (typeof predicate === 'function' && !predicate(getState, action)) {
|
|
return next(action);
|
|
}
|
|
|
|
var logEntry = {};
|
|
logBuffer.push(logEntry);
|
|
|
|
logEntry.started = _helpers.timer.now();
|
|
logEntry.startedTime = new Date();
|
|
logEntry.prevState = stateTransformer(getState());
|
|
logEntry.action = action;
|
|
|
|
var returnedValue = void 0;
|
|
if (logErrors) {
|
|
try {
|
|
returnedValue = next(action);
|
|
} catch (e) {
|
|
logEntry.error = errorTransformer(e);
|
|
}
|
|
} else {
|
|
returnedValue = next(action);
|
|
}
|
|
|
|
logEntry.took = _helpers.timer.now() - logEntry.started;
|
|
logEntry.nextState = stateTransformer(getState());
|
|
|
|
var diff = loggerOptions.diff && typeof diffPredicate === 'function' ? diffPredicate(getState, action) : loggerOptions.diff;
|
|
|
|
(0, _core.printBuffer)(logBuffer, _extends({}, loggerOptions, { diff: diff }));
|
|
logBuffer.length = 0;
|
|
|
|
if (logEntry.error) throw logEntry.error;
|
|
return returnedValue;
|
|
};
|
|
};
|
|
};
|
|
}
|
|
|
|
var defaultLogger = createLogger();
|
|
|
|
exports.defaults = _defaults2.default;
|
|
exports.logger = defaultLogger;
|
|
exports.default = createLogger;
|
|
|
|
/***/ },
|
|
/* 3 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
|
|
exports.printBuffer = printBuffer;
|
|
|
|
var _helpers = __webpack_require__(1);
|
|
|
|
var _diff = __webpack_require__(5);
|
|
|
|
var _diff2 = _interopRequireDefault(_diff);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
|
|
|
/**
|
|
* Get log level string based on supplied params
|
|
*
|
|
* @param {string | function | object} level - console[level]
|
|
* @param {object} action - selected action
|
|
* @param {array} payload - selected payload
|
|
* @param {string} type - log entry type
|
|
*
|
|
* @returns {string} level
|
|
*/
|
|
function getLogLevel(level, action, payload, type) {
|
|
switch (typeof level === 'undefined' ? 'undefined' : _typeof(level)) {
|
|
case 'object':
|
|
return typeof level[type] === 'function' ? level[type].apply(level, _toConsumableArray(payload)) : level[type];
|
|
case 'function':
|
|
return level(action);
|
|
default:
|
|
return level;
|
|
}
|
|
}
|
|
|
|
function defaultTitleFormatter(options) {
|
|
var timestamp = options.timestamp,
|
|
duration = options.duration;
|
|
|
|
|
|
return function (action, time, took) {
|
|
var parts = ['action'];
|
|
|
|
parts.push('%c' + String(action.type));
|
|
if (timestamp) parts.push('%c@ ' + time);
|
|
if (duration) parts.push('%c(in ' + took.toFixed(2) + ' ms)');
|
|
|
|
return parts.join(' ');
|
|
};
|
|
}
|
|
|
|
function printBuffer(buffer, options) {
|
|
var logger = options.logger,
|
|
actionTransformer = options.actionTransformer,
|
|
_options$titleFormatt = options.titleFormatter,
|
|
titleFormatter = _options$titleFormatt === undefined ? defaultTitleFormatter(options) : _options$titleFormatt,
|
|
collapsed = options.collapsed,
|
|
colors = options.colors,
|
|
level = options.level,
|
|
diff = options.diff;
|
|
|
|
|
|
buffer.forEach(function (logEntry, key) {
|
|
var started = logEntry.started,
|
|
startedTime = logEntry.startedTime,
|
|
action = logEntry.action,
|
|
prevState = logEntry.prevState,
|
|
error = logEntry.error;
|
|
var took = logEntry.took,
|
|
nextState = logEntry.nextState;
|
|
|
|
var nextEntry = buffer[key + 1];
|
|
|
|
if (nextEntry) {
|
|
nextState = nextEntry.prevState;
|
|
took = nextEntry.started - started;
|
|
}
|
|
|
|
// Message
|
|
var formattedAction = actionTransformer(action);
|
|
var isCollapsed = typeof collapsed === 'function' ? collapsed(function () {
|
|
return nextState;
|
|
}, action, logEntry) : collapsed;
|
|
|
|
var formattedTime = (0, _helpers.formatTime)(startedTime);
|
|
var titleCSS = colors.title ? 'color: ' + colors.title(formattedAction) + ';' : '';
|
|
var headerCSS = ['color: gray; font-weight: lighter;'];
|
|
headerCSS.push(titleCSS);
|
|
if (options.timestamp) headerCSS.push('color: gray; font-weight: lighter;');
|
|
if (options.duration) headerCSS.push('color: gray; font-weight: lighter;');
|
|
var title = titleFormatter(formattedAction, formattedTime, took);
|
|
|
|
// Render
|
|
try {
|
|
if (isCollapsed) {
|
|
if (colors.title) logger.groupCollapsed.apply(logger, ['%c ' + title].concat(headerCSS));else logger.groupCollapsed(title);
|
|
} else {
|
|
if (colors.title) logger.group.apply(logger, ['%c ' + title].concat(headerCSS));else logger.group(title);
|
|
}
|
|
} catch (e) {
|
|
logger.log(title);
|
|
}
|
|
|
|
var prevStateLevel = getLogLevel(level, formattedAction, [prevState], 'prevState');
|
|
var actionLevel = getLogLevel(level, formattedAction, [formattedAction], 'action');
|
|
var errorLevel = getLogLevel(level, formattedAction, [error, prevState], 'error');
|
|
var nextStateLevel = getLogLevel(level, formattedAction, [nextState], 'nextState');
|
|
|
|
if (prevStateLevel) {
|
|
if (colors.prevState) logger[prevStateLevel]('%c prev state', 'color: ' + colors.prevState(prevState) + '; font-weight: bold', prevState);else logger[prevStateLevel]('prev state', prevState);
|
|
}
|
|
|
|
if (actionLevel) {
|
|
if (colors.action) logger[actionLevel]('%c action ', 'color: ' + colors.action(formattedAction) + '; font-weight: bold', formattedAction);else logger[actionLevel]('action ', formattedAction);
|
|
}
|
|
|
|
if (error && errorLevel) {
|
|
if (colors.error) logger[errorLevel]('%c error ', 'color: ' + colors.error(error, prevState) + '; font-weight: bold;', error);else logger[errorLevel]('error ', error);
|
|
}
|
|
|
|
if (nextStateLevel) {
|
|
if (colors.nextState) logger[nextStateLevel]('%c next state', 'color: ' + colors.nextState(nextState) + '; font-weight: bold', nextState);else logger[nextStateLevel]('next state', nextState);
|
|
}
|
|
|
|
if (diff) {
|
|
(0, _diff2.default)(prevState, nextState, logger, isCollapsed);
|
|
}
|
|
|
|
try {
|
|
logger.groupEnd();
|
|
} catch (e) {
|
|
logger.log('\u2014\u2014 log end \u2014\u2014');
|
|
}
|
|
});
|
|
}
|
|
|
|
/***/ },
|
|
/* 4 */
|
|
/***/ function(module, exports) {
|
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = {
|
|
level: "log",
|
|
logger: console,
|
|
logErrors: true,
|
|
collapsed: undefined,
|
|
predicate: undefined,
|
|
duration: false,
|
|
timestamp: true,
|
|
stateTransformer: function stateTransformer(state) {
|
|
return state;
|
|
},
|
|
actionTransformer: function actionTransformer(action) {
|
|
return action;
|
|
},
|
|
errorTransformer: function errorTransformer(error) {
|
|
return error;
|
|
},
|
|
colors: {
|
|
title: function title() {
|
|
return "inherit";
|
|
},
|
|
prevState: function prevState() {
|
|
return "#9E9E9E";
|
|
},
|
|
action: function action() {
|
|
return "#03A9F4";
|
|
},
|
|
nextState: function nextState() {
|
|
return "#4CAF50";
|
|
},
|
|
error: function error() {
|
|
return "#F20404";
|
|
}
|
|
},
|
|
diff: false,
|
|
diffPredicate: undefined,
|
|
|
|
// Deprecated options
|
|
transformer: undefined
|
|
};
|
|
module.exports = exports["default"];
|
|
|
|
/***/ },
|
|
/* 5 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = diffLogger;
|
|
|
|
var _deepDiff = __webpack_require__(6);
|
|
|
|
var _deepDiff2 = _interopRequireDefault(_deepDiff);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
|
|
|
// https://github.com/flitbit/diff#differences
|
|
var dictionary = {
|
|
'E': {
|
|
color: '#2196F3',
|
|
text: 'CHANGED:'
|
|
},
|
|
'N': {
|
|
color: '#4CAF50',
|
|
text: 'ADDED:'
|
|
},
|
|
'D': {
|
|
color: '#F44336',
|
|
text: 'DELETED:'
|
|
},
|
|
'A': {
|
|
color: '#2196F3',
|
|
text: 'ARRAY:'
|
|
}
|
|
};
|
|
|
|
function style(kind) {
|
|
return 'color: ' + dictionary[kind].color + '; font-weight: bold';
|
|
}
|
|
|
|
function render(diff) {
|
|
var kind = diff.kind,
|
|
path = diff.path,
|
|
lhs = diff.lhs,
|
|
rhs = diff.rhs,
|
|
index = diff.index,
|
|
item = diff.item;
|
|
|
|
|
|
switch (kind) {
|
|
case 'E':
|
|
return [path.join('.'), lhs, '\u2192', rhs];
|
|
case 'N':
|
|
return [path.join('.'), rhs];
|
|
case 'D':
|
|
return [path.join('.')];
|
|
case 'A':
|
|
return [path.join('.') + '[' + index + ']', item];
|
|
default:
|
|
return [];
|
|
}
|
|
}
|
|
|
|
function diffLogger(prevState, newState, logger, isCollapsed) {
|
|
var diff = (0, _deepDiff2.default)(prevState, newState);
|
|
|
|
try {
|
|
if (isCollapsed) {
|
|
logger.groupCollapsed('diff');
|
|
} else {
|
|
logger.group('diff');
|
|
}
|
|
} catch (e) {
|
|
logger.log('diff');
|
|
}
|
|
|
|
if (diff) {
|
|
diff.forEach(function (elem) {
|
|
var kind = elem.kind;
|
|
|
|
var output = render(elem);
|
|
|
|
logger.log.apply(logger, ['%c ' + dictionary[kind].text, style(kind)].concat(_toConsumableArray(output)));
|
|
});
|
|
} else {
|
|
logger.log('\u2014\u2014 no diff \u2014\u2014');
|
|
}
|
|
|
|
try {
|
|
logger.groupEnd();
|
|
} catch (e) {
|
|
logger.log('\u2014\u2014 diff end \u2014\u2014 ');
|
|
}
|
|
}
|
|
module.exports = exports['default'];
|
|
|
|
/***/ },
|
|
/* 6 */
|
|
/***/ function(module, exports, __webpack_require__) {
|
|
|
|
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(global) {/*!
|
|
* deep-diff.
|
|
* Licensed under the MIT License.
|
|
*/
|
|
;(function(root, factory) {
|
|
'use strict';
|
|
if (true) {
|
|
// AMD. Register as an anonymous module.
|
|
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
|
|
return factory();
|
|
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
|
|
} else if (typeof exports === 'object') {
|
|
// Node. Does not work with strict CommonJS, but
|
|
// only CommonJS-like environments that support module.exports,
|
|
// like Node.
|
|
module.exports = factory();
|
|
} else {
|
|
// Browser globals (root is window)
|
|
root.DeepDiff = factory();
|
|
}
|
|
}(this, function(undefined) {
|
|
'use strict';
|
|
|
|
var $scope, conflict, conflictResolution = [];
|
|
if (typeof global === 'object' && global) {
|
|
$scope = global;
|
|
} else if (typeof window !== 'undefined') {
|
|
$scope = window;
|
|
} else {
|
|
$scope = {};
|
|
}
|
|
conflict = $scope.DeepDiff;
|
|
if (conflict) {
|
|
conflictResolution.push(
|
|
function() {
|
|
if ('undefined' !== typeof conflict && $scope.DeepDiff === accumulateDiff) {
|
|
$scope.DeepDiff = conflict;
|
|
conflict = undefined;
|
|
}
|
|
});
|
|
}
|
|
|
|
// nodejs compatible on server side and in the browser.
|
|
function inherits(ctor, superCtor) {
|
|
ctor.super_ = superCtor;
|
|
ctor.prototype = Object.create(superCtor.prototype, {
|
|
constructor: {
|
|
value: ctor,
|
|
enumerable: false,
|
|
writable: true,
|
|
configurable: true
|
|
}
|
|
});
|
|
}
|
|
|
|
function Diff(kind, path) {
|
|
Object.defineProperty(this, 'kind', {
|
|
value: kind,
|
|
enumerable: true
|
|
});
|
|
if (path && path.length) {
|
|
Object.defineProperty(this, 'path', {
|
|
value: path,
|
|
enumerable: true
|
|
});
|
|
}
|
|
}
|
|
|
|
function DiffEdit(path, origin, value) {
|
|
DiffEdit.super_.call(this, 'E', path);
|
|
Object.defineProperty(this, 'lhs', {
|
|
value: origin,
|
|
enumerable: true
|
|
});
|
|
Object.defineProperty(this, 'rhs', {
|
|
value: value,
|
|
enumerable: true
|
|
});
|
|
}
|
|
inherits(DiffEdit, Diff);
|
|
|
|
function DiffNew(path, value) {
|
|
DiffNew.super_.call(this, 'N', path);
|
|
Object.defineProperty(this, 'rhs', {
|
|
value: value,
|
|
enumerable: true
|
|
});
|
|
}
|
|
inherits(DiffNew, Diff);
|
|
|
|
function DiffDeleted(path, value) {
|
|
DiffDeleted.super_.call(this, 'D', path);
|
|
Object.defineProperty(this, 'lhs', {
|
|
value: value,
|
|
enumerable: true
|
|
});
|
|
}
|
|
inherits(DiffDeleted, Diff);
|
|
|
|
function DiffArray(path, index, item) {
|
|
DiffArray.super_.call(this, 'A', path);
|
|
Object.defineProperty(this, 'index', {
|
|
value: index,
|
|
enumerable: true
|
|
});
|
|
Object.defineProperty(this, 'item', {
|
|
value: item,
|
|
enumerable: true
|
|
});
|
|
}
|
|
inherits(DiffArray, Diff);
|
|
|
|
function arrayRemove(arr, from, to) {
|
|
var rest = arr.slice((to || from) + 1 || arr.length);
|
|
arr.length = from < 0 ? arr.length + from : from;
|
|
arr.push.apply(arr, rest);
|
|
return arr;
|
|
}
|
|
|
|
function realTypeOf(subject) {
|
|
var type = typeof subject;
|
|
if (type !== 'object') {
|
|
return type;
|
|
}
|
|
|
|
if (subject === Math) {
|
|
return 'math';
|
|
} else if (subject === null) {
|
|
return 'null';
|
|
} else if (Array.isArray(subject)) {
|
|
return 'array';
|
|
} else if (Object.prototype.toString.call(subject) === '[object Date]') {
|
|
return 'date';
|
|
} else if (typeof subject.toString !== 'undefined' && /^\/.*\//.test(subject.toString())) {
|
|
return 'regexp';
|
|
}
|
|
return 'object';
|
|
}
|
|
|
|
function deepDiff(lhs, rhs, changes, prefilter, path, key, stack) {
|
|
path = path || [];
|
|
var currentPath = path.slice(0);
|
|
if (typeof key !== 'undefined') {
|
|
if (prefilter) {
|
|
if (typeof(prefilter) === 'function' && prefilter(currentPath, key)) { return; }
|
|
else if (typeof(prefilter) === 'object') {
|
|
if (prefilter.prefilter && prefilter.prefilter(currentPath, key)) { return; }
|
|
if (prefilter.normalize) {
|
|
var alt = prefilter.normalize(currentPath, key, lhs, rhs);
|
|
if (alt) {
|
|
lhs = alt[0];
|
|
rhs = alt[1];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
currentPath.push(key);
|
|
}
|
|
|
|
// Use string comparison for regexes
|
|
if (realTypeOf(lhs) === 'regexp' && realTypeOf(rhs) === 'regexp') {
|
|
lhs = lhs.toString();
|
|
rhs = rhs.toString();
|
|
}
|
|
|
|
var ltype = typeof lhs;
|
|
var rtype = typeof rhs;
|
|
if (ltype === 'undefined') {
|
|
if (rtype !== 'undefined') {
|
|
changes(new DiffNew(currentPath, rhs));
|
|
}
|
|
} else if (rtype === 'undefined') {
|
|
changes(new DiffDeleted(currentPath, lhs));
|
|
} else if (realTypeOf(lhs) !== realTypeOf(rhs)) {
|
|
changes(new DiffEdit(currentPath, lhs, rhs));
|
|
} else if (Object.prototype.toString.call(lhs) === '[object Date]' && Object.prototype.toString.call(rhs) === '[object Date]' && ((lhs - rhs) !== 0)) {
|
|
changes(new DiffEdit(currentPath, lhs, rhs));
|
|
} else if (ltype === 'object' && lhs !== null && rhs !== null) {
|
|
stack = stack || [];
|
|
if (stack.indexOf(lhs) < 0) {
|
|
stack.push(lhs);
|
|
if (Array.isArray(lhs)) {
|
|
var i, len = lhs.length;
|
|
for (i = 0; i < lhs.length; i++) {
|
|
if (i >= rhs.length) {
|
|
changes(new DiffArray(currentPath, i, new DiffDeleted(undefined, lhs[i])));
|
|
} else {
|
|
deepDiff(lhs[i], rhs[i], changes, prefilter, currentPath, i, stack);
|
|
}
|
|
}
|
|
while (i < rhs.length) {
|
|
changes(new DiffArray(currentPath, i, new DiffNew(undefined, rhs[i++])));
|
|
}
|
|
} else {
|
|
var akeys = Object.keys(lhs);
|
|
var pkeys = Object.keys(rhs);
|
|
akeys.forEach(function(k, i) {
|
|
var other = pkeys.indexOf(k);
|
|
if (other >= 0) {
|
|
deepDiff(lhs[k], rhs[k], changes, prefilter, currentPath, k, stack);
|
|
pkeys = arrayRemove(pkeys, other);
|
|
} else {
|
|
deepDiff(lhs[k], undefined, changes, prefilter, currentPath, k, stack);
|
|
}
|
|
});
|
|
pkeys.forEach(function(k) {
|
|
deepDiff(undefined, rhs[k], changes, prefilter, currentPath, k, stack);
|
|
});
|
|
}
|
|
stack.length = stack.length - 1;
|
|
}
|
|
} else if (lhs !== rhs) {
|
|
if (!(ltype === 'number' && isNaN(lhs) && isNaN(rhs))) {
|
|
changes(new DiffEdit(currentPath, lhs, rhs));
|
|
}
|
|
}
|
|
}
|
|
|
|
function accumulateDiff(lhs, rhs, prefilter, accum) {
|
|
accum = accum || [];
|
|
deepDiff(lhs, rhs,
|
|
function(diff) {
|
|
if (diff) {
|
|
accum.push(diff);
|
|
}
|
|
},
|
|
prefilter);
|
|
return (accum.length) ? accum : undefined;
|
|
}
|
|
|
|
function applyArrayChange(arr, index, change) {
|
|
if (change.path && change.path.length) {
|
|
var it = arr[index],
|
|
i, u = change.path.length - 1;
|
|
for (i = 0; i < u; i++) {
|
|
it = it[change.path[i]];
|
|
}
|
|
switch (change.kind) {
|
|
case 'A':
|
|
applyArrayChange(it[change.path[i]], change.index, change.item);
|
|
break;
|
|
case 'D':
|
|
delete it[change.path[i]];
|
|
break;
|
|
case 'E':
|
|
case 'N':
|
|
it[change.path[i]] = change.rhs;
|
|
break;
|
|
}
|
|
} else {
|
|
switch (change.kind) {
|
|
case 'A':
|
|
applyArrayChange(arr[index], change.index, change.item);
|
|
break;
|
|
case 'D':
|
|
arr = arrayRemove(arr, index);
|
|
break;
|
|
case 'E':
|
|
case 'N':
|
|
arr[index] = change.rhs;
|
|
break;
|
|
}
|
|
}
|
|
return arr;
|
|
}
|
|
|
|
function applyChange(target, source, change) {
|
|
if (target && source && change && change.kind) {
|
|
var it = target,
|
|
i = -1,
|
|
last = change.path ? change.path.length - 1 : 0;
|
|
while (++i < last) {
|
|
if (typeof it[change.path[i]] === 'undefined') {
|
|
it[change.path[i]] = (typeof change.path[i] === 'number') ? [] : {};
|
|
}
|
|
it = it[change.path[i]];
|
|
}
|
|
switch (change.kind) {
|
|
case 'A':
|
|
applyArrayChange(change.path ? it[change.path[i]] : it, change.index, change.item);
|
|
break;
|
|
case 'D':
|
|
delete it[change.path[i]];
|
|
break;
|
|
case 'E':
|
|
case 'N':
|
|
it[change.path[i]] = change.rhs;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
function revertArrayChange(arr, index, change) {
|
|
if (change.path && change.path.length) {
|
|
// the structure of the object at the index has changed...
|
|
var it = arr[index],
|
|
i, u = change.path.length - 1;
|
|
for (i = 0; i < u; i++) {
|
|
it = it[change.path[i]];
|
|
}
|
|
switch (change.kind) {
|
|
case 'A':
|
|
revertArrayChange(it[change.path[i]], change.index, change.item);
|
|
break;
|
|
case 'D':
|
|
it[change.path[i]] = change.lhs;
|
|
break;
|
|
case 'E':
|
|
it[change.path[i]] = change.lhs;
|
|
break;
|
|
case 'N':
|
|
delete it[change.path[i]];
|
|
break;
|
|
}
|
|
} else {
|
|
// the array item is different...
|
|
switch (change.kind) {
|
|
case 'A':
|
|
revertArrayChange(arr[index], change.index, change.item);
|
|
break;
|
|
case 'D':
|
|
arr[index] = change.lhs;
|
|
break;
|
|
case 'E':
|
|
arr[index] = change.lhs;
|
|
break;
|
|
case 'N':
|
|
arr = arrayRemove(arr, index);
|
|
break;
|
|
}
|
|
}
|
|
return arr;
|
|
}
|
|
|
|
function revertChange(target, source, change) {
|
|
if (target && source && change && change.kind) {
|
|
var it = target,
|
|
i, u;
|
|
u = change.path.length - 1;
|
|
for (i = 0; i < u; i++) {
|
|
if (typeof it[change.path[i]] === 'undefined') {
|
|
it[change.path[i]] = {};
|
|
}
|
|
it = it[change.path[i]];
|
|
}
|
|
switch (change.kind) {
|
|
case 'A':
|
|
// Array was modified...
|
|
// it will be an array...
|
|
revertArrayChange(it[change.path[i]], change.index, change.item);
|
|
break;
|
|
case 'D':
|
|
// Item was deleted...
|
|
it[change.path[i]] = change.lhs;
|
|
break;
|
|
case 'E':
|
|
// Item was edited...
|
|
it[change.path[i]] = change.lhs;
|
|
break;
|
|
case 'N':
|
|
// Item is new...
|
|
delete it[change.path[i]];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
function applyDiff(target, source, filter) {
|
|
if (target && source) {
|
|
var onChange = function(change) {
|
|
if (!filter || filter(target, source, change)) {
|
|
applyChange(target, source, change);
|
|
}
|
|
};
|
|
deepDiff(target, source, onChange);
|
|
}
|
|
}
|
|
|
|
Object.defineProperties(accumulateDiff, {
|
|
|
|
diff: {
|
|
value: accumulateDiff,
|
|
enumerable: true
|
|
},
|
|
observableDiff: {
|
|
value: deepDiff,
|
|
enumerable: true
|
|
},
|
|
applyDiff: {
|
|
value: applyDiff,
|
|
enumerable: true
|
|
},
|
|
applyChange: {
|
|
value: applyChange,
|
|
enumerable: true
|
|
},
|
|
revertChange: {
|
|
value: revertChange,
|
|
enumerable: true
|
|
},
|
|
isConflict: {
|
|
value: function() {
|
|
return 'undefined' !== typeof conflict;
|
|
},
|
|
enumerable: true
|
|
},
|
|
noConflict: {
|
|
value: function() {
|
|
if (conflictResolution) {
|
|
conflictResolution.forEach(function(it) {
|
|
it();
|
|
});
|
|
conflictResolution = null;
|
|
}
|
|
return accumulateDiff;
|
|
},
|
|
enumerable: true
|
|
}
|
|
});
|
|
|
|
return accumulateDiff;
|
|
}));
|
|
|
|
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
|
|
|
|
/***/ }
|
|
/******/ ])
|
|
});
|
|
; |