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

realdom

Package Overview
Dependencies
Maintainers
0
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

realdom - npm Package Compare versions

Comparing version 0.0.2 to 0.0.3

8

package.json
{
"name": "realdom",
"version": "0.0.2",
"version": "0.0.3",
"author": "Fedot Kriutchenko <fodyadev@gmail.com>",

@@ -8,6 +8,4 @@ "description": "",

"type": "module",
"exports": {
},
"dependencies": {
}
"exports": {},
"dependencies": {}
}

@@ -1,98 +0,142 @@

import { runWithState } from './state.js';
import { Builder } from './common.js';
import { textContent, NodeOperation } from './operators.js';
import { runWithState, getCurrentHandler } from './state.js';
import { argsToArray, isReactive, kebab } from './common.js';
const nodeUpdates = new WeakMap();
class NodeDeferredUpdate {
constructor(pos, funcs, state) {
this.pos = pos;
this.funcs = funcs;
this.state = state;
}
}
let tree = null;
let treeSymbol = Symbol();
export class Tree {
list = []
i = 0
class LazyElement {
constructor(build) {
this.build = build;
}
create(ns) {
const node = this.build(ns);
const updates = nodeUpdates.get(node);
if (updates) for (const {pos, funcs, state} of updates) {
let elem = node;
for (const i of pos) elem = elem.childNodes[i];
for (const func of funcs) func(elem, state);
tmpl = null
init() {
let ns;
let l = 0, node;
const nodes = [];
for (const item of this.list) switch (item.constructor) {
case NodeOpen:
const elem = document.createElement(item.tag);
if (node) node.appendChild(elem); else this.tmpl = elem;
node = nodes[l] = elem;
l++;
break;
case NodeOperation:
if (!item.rerender) item.func(node, item.names, item.args);
break;
case NodeText:
const text = document.createTextNode(item.value);
nodes[l - 1].appendChild(text);
break;
case NodeClose:
l--;
node = nodes[l - 1];
break;
}
return node;
}
}
const unwrapContents = (item) => {
if (Builder.isBuilder(item)) item = Builder.launch(item);
if (Array.isArray(item)) return item.flatMap(unwrapContents);
return item;
}
export const Element = (tag, ...contents) => new LazyElement(ns => {
let node, textNode = false;
if (tag === '') {
textNode = true;
node = document.createTextNode('');
} else if (tag === '!') {
textNode = true;
node = document.createComment('')
} else {
if (tag == 'svg') ns = 'http://www.w3.org/2000/svg';
if (ns) node = document.createElementNS(ns, tag);
else node = document.createElement(tag);
hydrate(root) {
let l = 0, node;
const path = [];
const nodes = [];
for (const item of this.list) switch (item.constructor) {
case NodeOpen:
node = nodes[l] = node ? node.childNodes[path[l - 1]] : root;
path[l] = 0;
l++;
break;
case NodeOperation:
if (item.rerender) item.func(node, item.names, item.args);
break;
case NodeText:
if (item.rerender) node.textContent = item.value;
break;
case NodeClose:
l--;
node = nodes[l - 1];
path[l - 1]++;
break;
}
return root;
}
const selfUpdates = new NodeDeferredUpdate([], [], null);
const treeUpdates = [];
update(treeNode) {
const prevTree = tree;
tree = this;
const applyUpdate = (item) => {
if (item.deferred) selfUpdates.funcs.push(item.func);
else item.func(node);
this.i = 0;
treeNode();
if (!this.tmpl) { this.init(); console.log(this); }
tree = prevTree;
}
}
let cid = -1;
const appendChild = (child) => {
cid++;
const childUpdates = nodeUpdates.get(child);
if (childUpdates) for (const {pos, funcs, state} of childUpdates) {
treeUpdates.push(new NodeDeferredUpdate([cid, ...pos], funcs, state));
}
node.appendChild(child);
}
const symbol = Symbol();
function builder(effect) {
let names = [];
const tasks = [];
for (const item of unwrapContents(contents)) {
if (item instanceof NodeOperation) {
applyUpdate(item);
} else if (item instanceof LazyElement) {
appendChild(item.build(ns));
const call = (...args) => {
if (args.length === 0) {
for (const t of tasks) effect(t.names, t.args);
} else {
if (textNode) applyUpdate(Builder.launch(textContent(item))[0]);
else appendChild(Element('', textContent(item)).build(ns));
tasks.push({ names, args });
names = [];
}
return p;
}
const get = (_, k) => {
if (k === treeSymbol) return true;
names.push(k);
return p;
}
let p; return p = new Proxy(call, { get });
}
if (selfUpdates.funcs.length) treeUpdates.push(selfUpdates);
if (treeUpdates.length) nodeUpdates.set(node, treeUpdates);
return node;
export const Builder = (effect) => new Proxy(
(...a) => builder(effect)(...a),
{ get: (_, k) => builder(effect)[k] }
);
class NodeOpen {
constructor(tag) { this.tag = tag; }
}
class NodeOperation {
constructor(func, names) { this.func = func; this.names = names; }
update(rerender, args) { this.rerender = rerender; this.args = args; }
}
class NodeText {
constructor(value) { this.value = value; }
update(value) { this.rerender = this.value != value; this.value = value; }
}
class NodeClose {}
export const Operator = (reactive, func) => Builder((names, args) => {
(tree.list[tree.i++] ??= new NodeOperation(func, names)).update(
typeof reactive == 'function' ? reactive(args) : reactive,
args
);
});
export const Component = (func, elem) => {
const namespaced = {};
return function componentInstance(...args) {
const state = {};
runWithState(state, func, null, args, null);
return new LazyElement(ns => {
const node = namespaced[ns] ??= elem.build(ns);
const clone = node.cloneNode(true);
const updates = nodeUpdates.get(node);
if (updates?.length) nodeUpdates.set(clone, updates.map(u =>
new NodeDeferredUpdate(u.pos, u.funcs, u.state ?? state)
));
return clone;
});
export const Element = (tag, ...content) => {
const launch = () => {
tree.list[tree.i++] ??= new NodeOpen(
tag[0].toLowerCase() + kebab(tag.slice(1))
);
for (const item of content) {
switch (item[treeSymbol]) {
case true: item(); break;
default: (tree.list[tree.i++] ??= new NodeText(item)).update(item);
}
}
tree.list[tree.i++] ??= new NodeClose();
}
launch[treeSymbol] = true;
return launch;
}
export const Component = func => {
const compTree = new Tree();
let i = 0;
return (...args) => {
compTree.update(func(...args));
return compTree.hydrate(compTree.tmpl.cloneNode(true));
}
}
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