Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

melody-devtools

Package Overview
Dependencies
Maintainers
3
Versions
90
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

melody-devtools - npm Package Compare versions

Comparing version 1.2.0-commit.f9b4ed0d to 1.2.0-f61c830.4

LICENSE

438

lib/index.js

@@ -1,437 +0,1 @@

'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var melodyIdom = require('melody-idom');
/**
* Copyright 2017 trivago N.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Return a ReactElement-compatible object for the current state of a preact
* component.
*/
function createReactElement(component) {
if (!component.constructor.displayName) {
component.constructor.displayName = component.displayName;
}
return {
type: component.constructor,
key: component.el && melodyIdom.getNodeData(component.el).key,
ref: null, // Unsupported
props: component.props || component.ownProps
};
}
/**
* Create a ReactDOMComponent-compatible object for a given DOM node rendered
* by preact.
*
* This implements the subset of the ReactDOMComponent interface that
* React DevTools requires in order to display DOM nodes in the inspector with
* the correct type and properties.
*
* @param {Node} node
*/
function createReactDOMComponent(node) {
var childNodes = node.nodeType === Node.ELEMENT_NODE ? Array.from(node.childNodes) : [];
var isText = node.nodeType === Node.TEXT_NODE;
return {
// --- ReactDOMComponent interface
_currentElement: isText ? node.textContent : {
type: node.nodeName.toLowerCase()
},
_renderedChildren: childNodes.map(function (child) {
var nodeData = melodyIdom.getNodeData(child);
if (nodeData && nodeData.componentInstance) {
return updateReactComponent(nodeData.componentInstance);
}
return updateReactComponent(child);
}),
_stringText: isText ? node.textContent : null,
publicInstance: node,
// --- Additional properties used by preact devtools
// A flag indicating whether the devtools have been notified about the
// existence of this component instance yet.
// This is used to send the appropriate notifications when DOM components
// are added or updated between composite component updates.
_inDevTools: false,
node: node
};
}
/**
* Return a ReactCompositeComponent-compatible object for a given preact
* component instance.
*
* This implements the subset of the ReactCompositeComponent interface that
* the DevTools requires in order to walk the component tree and inspect the
* component's properties.
*
* See https://github.com/facebook/react-devtools/blob/e31ec5825342eda570acfc9bcb43a44258fceb28/backend/getData.js
*/
function createReactCompositeComponent(component) {
var _currentElement = createReactElement(component);
var node = component.el;
var instance = {
// --- ReactDOMComponent properties
name: component.displayName,
getName: function getName() {
return component.displayName;
},
_currentElement: _currentElement,
props: component.props || component.ownProps,
state: component.state || component.renderProps,
// forceUpdate: () => {
// enqueueComponent(component);
// },
// setState: (state) => {
// if (component.state) {
// Object.assign(component.state, state);
// enqueueComponent(component);
// }
// },
// --- Additional properties used by preact devtools
node: node
};
// React DevTools exposes the `_instance` field of the selected item in the
// component tree as `$r` in the console. `_instance` must refer to a
// React Component (or compatible) class instance with `props` and `state`
// fields and `setState()`, `forceUpdate()` methods.
//instance._instance = component;
instance._instance = {
get props() {
return component.props || component.ownProps;
},
get state() {
return component.state || component.renderProps;
},
get refs() {
return component.refs;
},
setState: function setState(state) {
Object.assign(component.state, state);
},
forceUpdate: function forceUpdate() {
melodyIdom.enqueueComponent(component);
},
dispatch: function dispatch(action) {
if (component.dispatch) {
component.dispatch(action);
}
}
};
// If the root node returned by this component instance's render function
// was itself a composite component, there will be a `_component` property
// containing the child component instance.
if (component.childInstance) {
instance._renderedComponent = updateReactComponent(component.childInstance);
} else if (node) {
// Otherwise, if the render() function returned an HTML/SVG element,
// create a ReactDOMComponent-like object for the DOM node itself.
instance._renderedComponent = updateReactComponent(node);
}
return instance;
}
/**
* Map of Component|Node to ReactDOMComponent|ReactCompositeComponent-like
* object.
*
* The same React*Component instance must be used when notifying devtools
* about the initial mount of a component and subsequent updates.
*/
var instanceMap = typeof Map === 'function' && new Map();
/**
* Update (and create if necessary) the ReactDOMComponent|ReactCompositeComponent-like
* instance for a given preact component instance or DOM Node.
*
* @param {Component|Node} componentOrNode
*/
function updateReactComponent(componentOrNode) {
var newInstance = componentOrNode instanceof Node ? createReactDOMComponent(componentOrNode) : createReactCompositeComponent(componentOrNode);
if (instanceMap.has(componentOrNode)) {
var inst = instanceMap.get(componentOrNode);
Object.assign(inst, newInstance);
return inst;
}
instanceMap.set(componentOrNode, newInstance);
return newInstance;
}
function nextRootKey(roots) {
return '.' + Object.keys(roots).length;
}
/**
* Find all root component instances rendered by preact in `node`'s children
* and add them to the `roots` map.
*
* @param {DOMElement} node
* @param {[key: string] => ReactDOMComponent|ReactCompositeComponent}
*/
function findRoots(node, roots) {
Array.from(node.childNodes).forEach(function (child) {
var nodeData = melodyIdom.getNodeData(child);
if (nodeData && nodeData.componentInstance) {
roots[nextRootKey(roots)] = updateReactComponent(nodeData.componentInstance);
} else {
findRoots(child, roots);
}
});
}
/**
* Create a bridge for exposing preact's component tree to React DevTools.
*
* It creates implementations of the interfaces that ReactDOM passes to
* devtools to enable it to query the component tree and hook into component
* updates.
*
* See https://github.com/facebook/react/blob/59ff7749eda0cd858d5ee568315bcba1be75a1ca/src/renderers/dom/ReactDOM.js
* for how ReactDOM exports its internals for use by the devtools and
* the `attachRenderer()` function in
* https://github.com/facebook/react-devtools/blob/e31ec5825342eda570acfc9bcb43a44258fceb28/backend/attachRenderer.js
* for how the devtools consumes the resulting objects.
*/
function createDevToolsBridge() {
// The devtools has different paths for interacting with the renderers from
// React Native, legacy React DOM and current React DOM.
//
// Here we emulate the interface for the current React DOM (v15+) lib.
// ReactDOMComponentTree-like object
var ComponentTree = {
getNodeFromInstance: function getNodeFromInstance(instance) {
return instance.node;
},
getClosestInstanceFromNode: function getClosestInstanceFromNode(rootNode) {
var node = rootNode;
while (node && !melodyIdom.getNodeData(node).componentInstance) {
node = node.parentNode;
}
return node ? updateReactComponent(melodyIdom.getNodeData(node).componentInstance) : null;
}
};
// Map of root ID (the ID is unimportant) to component instance.
var roots = {};
findRoots(document.body, roots);
// ReactMount-like object
//
// Used by devtools to discover the list of root component instances and get
// notified when new root components are rendered.
var Mount = {
_instancesByReactRootID: roots,
// Stub - React DevTools expects to find this method and replace it
// with a wrapper in order to observe new root components being added
_renderNewRootComponent: function _renderNewRootComponent() /* instance, ... */{}
};
// ReactReconciler-like object
var Reconciler = {
// Stubs - React DevTools expects to find these methods and replace them
// with wrappers in order to observe components being mounted, updated and
// unmounted
mountComponent: function mountComponent() /* instance, ... */{},
performUpdateIfNecessary: function performUpdateIfNecessary() /* instance, ... */{},
receiveComponent: function receiveComponent() /* instance, ... */{},
unmountComponent: function unmountComponent() /* instance, ... */{}
};
/** Notify devtools that a new component instance has been mounted into the DOM. */
var componentAdded = function componentAdded(component) {
var instance = updateReactComponent(component);
if (isRootComponent(component)) {
instance._rootID = nextRootKey(roots);
roots[instance._rootID] = instance;
Mount._renderNewRootComponent(instance);
}
visitNonCompositeChildren(instance, function (childInst) {
childInst._inDevTools = true;
Reconciler.mountComponent(childInst);
});
Reconciler.mountComponent(instance);
};
/** Notify devtools that a component has been updated with new props/state. */
var componentUpdated = function componentUpdated(component) {
var prevRenderedChildren = [];
visitNonCompositeChildren(instanceMap.get(component), function (childInst) {
prevRenderedChildren.push(childInst);
});
// Notify devtools about updates to this component and any non-composite
// children
var instance = updateReactComponent(component);
Reconciler.receiveComponent(instance);
visitNonCompositeChildren(instance, function (childInst) {
if (!childInst._inDevTools) {
// New DOM child component
childInst._inDevTools = true;
Reconciler.mountComponent(childInst);
} else {
// Updated DOM child component
Reconciler.receiveComponent(childInst);
}
});
// For any non-composite children that were removed by the latest render,
// remove the corresponding ReactDOMComponent-like instances and notify
// the devtools
prevRenderedChildren.forEach(function (childInst) {
if (!document.body.contains(childInst.node)) {
instanceMap.delete(childInst.node);
Reconciler.unmountComponent(childInst);
}
});
};
/** Notify devtools that a component has been unmounted from the DOM. */
var componentRemoved = function componentRemoved(component) {
var instance = updateReactComponent(component);
visitNonCompositeChildren(function (childInst) {
instanceMap.delete(childInst.node);
Reconciler.unmountComponent(childInst);
});
Reconciler.unmountComponent(instance);
instanceMap.delete(component);
if (instance._rootID) {
delete roots[instance._rootID];
}
};
return {
componentAdded: componentAdded,
componentUpdated: componentUpdated,
componentRemoved: componentRemoved,
// Interfaces passed to devtools via __REACT_DEVTOOLS_GLOBAL_HOOK__.inject()
ComponentTree: ComponentTree,
Mount: Mount,
Reconciler: Reconciler
};
}
/**
* Return `true` if a preact component is a top level component rendered by
* `render()` into a container Element.
*/
function isRootComponent(component) {
var parentInstance = melodyIdom.getParent(component);
if (parentInstance === undefined) {
return true;
} else if (parentInstance.childInstance !== undefined) {
return isRootComponent(parentInstance);
}
return false;
}
/**
* Visit all child instances of a ReactCompositeComponent-like object that are
* not composite components (ie. they represent DOM elements or text)
*
* @param {Component} component
* @param {(Component) => void} visitor
*/
function visitNonCompositeChildren(component, visitor) {
if (component._renderedComponent) {
if (!component._renderedComponent.componentInstance) {
visitor(component._renderedComponent);
visitNonCompositeChildren(component._renderedComponent, visitor);
}
} else if (component._renderedChildren) {
component._renderedChildren.forEach(function (child) {
visitor(child);
if (!child.componentInstance) {
visitNonCompositeChildren(child, visitor);
}
});
}
}
/**
* Create a bridge between the preact component tree and React's dev tools
* and register it.
*
* After this function is called, the React Dev Tools should be able to detect
* "React" on the page and show the component tree.
*
* This function hooks into preact VNode creation in order to expose functional
* components correctly, so it should be called before the root component(s)
* are rendered.
*
* Returns a cleanup function which unregisters the hooks.
*/
function initDevTools() {
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
// React DevTools are not installed
return;
}
// Notify devtools when preact components are mounted, updated or unmounted
var bridge = createDevToolsBridge();
var nextAfterMount = melodyIdom.options.afterMount;
melodyIdom.options.afterMount = function (component) {
bridge.componentAdded(component);
if (nextAfterMount) {
nextAfterMount(component);
}
};
var nextAfterUpdate = melodyIdom.options.afterUpdate;
melodyIdom.options.afterUpdate = function (component) {
bridge.componentUpdated(component);
if (nextAfterUpdate) {
nextAfterUpdate(component);
}
};
var nextBeforeUnmount = melodyIdom.options.beforeUnmount;
melodyIdom.options.beforeUnmount = function (component) {
bridge.componentRemoved(component);
if (nextBeforeUnmount) {
nextBeforeUnmount(component);
}
};
// Notify devtools about this instance of "React"
__REACT_DEVTOOLS_GLOBAL_HOOK__.inject(bridge);
return function () {
melodyIdom.options.afterMount = nextAfterMount;
melodyIdom.options.afterUpdate = nextAfterUpdate;
melodyIdom.options.beforeUnmount = nextBeforeUnmount;
};
}
exports.initDevTools = initDevTools;
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var c=require("melody-idom");function r(n){return n.constructor.displayName||(n.constructor.displayName=n.displayName),{type:n.constructor,key:n.el&&c.getNodeData(n.el).key,ref:null,props:n.props||n.ownProps}}function t(n){var e=n.nodeType===Node.ELEMENT_NODE?Array.from(n.childNodes):[],o=n.nodeType===Node.TEXT_NODE;return{_currentElement:o?n.textContent:{type:n.nodeName.toLowerCase()},_renderedChildren:e.map(function(n){var e=c.getNodeData(n);return e&&e.componentInstance?p(e.componentInstance):p(n)}),_stringText:o?n.textContent:null,publicInstance:n,_inDevTools:!1,node:n}}function a(e){var n=r(e),o=e.el,t={name:e.displayName,getName:function(){return e.displayName},_currentElement:n,props:e.props||e.ownProps,state:e.state||e.renderProps,node:o};return t._instance={get props(){return e.props||e.ownProps},get state(){return e.state||e.renderProps},get refs(){return e.refs},setState:function(n){Object.assign(e.state,n)},forceUpdate:function(){c.enqueueComponent(e)},dispatch:function(n){e.dispatch&&e.dispatch(n)}},e.childInstance?t._renderedComponent=p(e.childInstance):o&&(t._renderedComponent=p(o)),t}var d="function"==typeof Map&&new Map;function p(n){var e=n instanceof Node?t(n):a(n);if(d.has(n)){var o=d.get(n);return Object.assign(o,e),o}return d.set(n,e),e}function u(n){return"."+Object.keys(n).length}function i(n,o){Array.from(n.childNodes).forEach(function(n){var e=c.getNodeData(n);e&&e.componentInstance?o[u(o)]=p(e.componentInstance):i(n,o)})}function n(){var n={getNodeFromInstance:function(n){return n.node},getClosestInstanceFromNode:function(n){for(var e=n;e&&!c.getNodeData(e).componentInstance;)e=e.parentNode;return e?p(c.getNodeData(e).componentInstance):null}},o={};i(document.body,o);var t={_instancesByReactRootID:o,_renderNewRootComponent:function(){}},r={mountComponent:function(){},performUpdateIfNecessary:function(){},receiveComponent:function(){},unmountComponent:function(){}};return{componentAdded:function(n){var e=p(n);s(n)&&(e._rootID=u(o),o[e._rootID]=e,t._renderNewRootComponent(e)),m(e,function(n){n._inDevTools=!0,r.mountComponent(n)}),r.mountComponent(e)},componentUpdated:function(n){var e=[];m(d.get(n),function(n){e.push(n)});var o=p(n);r.receiveComponent(o),m(o,function(n){n._inDevTools?r.receiveComponent(n):(n._inDevTools=!0,r.mountComponent(n))}),e.forEach(function(n){document.body.contains(n.node)||(d.delete(n.node),r.unmountComponent(n))})},componentRemoved:function(n){var e=p(n);m(function(n){d.delete(n.node),r.unmountComponent(n)}),r.unmountComponent(e),d.delete(n),e._rootID&&delete o[e._rootID]},ComponentTree:n,Mount:t,Reconciler:r}}function s(n){var e=c.getParent(n);return void 0===e||void 0!==e.childInstance&&s(e)}function m(n,e){n._renderedComponent?n._renderedComponent.componentInstance||(e(n._renderedComponent),m(n._renderedComponent,e)):n._renderedChildren&&n._renderedChildren.forEach(function(n){e(n),n.componentInstance||m(n,e)})}function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var e=n(),o=c.options.afterMount;c.options.afterMount=function(n){e.componentAdded(n),o&&o(n)};var t=c.options.afterUpdate;c.options.afterUpdate=function(n){e.componentUpdated(n),t&&t(n)};var r=c.options.beforeUnmount;return c.options.beforeUnmount=function(n){e.componentRemoved(n),r&&r(n)},__REACT_DEVTOOLS_GLOBAL_HOOK__.inject(e),function(){c.options.afterMount=o,c.options.afterUpdate=t,c.options.beforeUnmount=r}}}exports.initDevTools=e;
{
"name": "melody-devtools",
"version": "1.2.0-commit.f9b4ed0d",
"version": "1.2.0-f61c830.4+f61c830",
"description": "",

@@ -16,5 +16,3 @@ "main": "./lib/index.js",

},
"devDependencies": {
"rollup-plugin-babel": "^2.6.1"
}
"gitHead": "f61c8303bc847d41f4005c1c969510332ece7d1d"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc