Skip to content

Commit

Permalink
Refactor to move implementation to lib/
Browse files Browse the repository at this point in the history
  • Loading branch information
wooorm committed Jan 23, 2023
1 parent 9dc0e7a commit dc17b1d
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 100 deletions.
102 changes: 2 additions & 100 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,103 +1,5 @@
/**
* @typedef {import('unist').Parent} Parent
* @typedef {import('unist').Node} Node
*
* @typedef ProxyFields
* @property {Parent|null} parent
* Parent link (or `null` for the root).
* @property {Node} node
* Link to the original node
*
* @typedef {Node & ProxyFields} Proxy
* Proxied node
* @typedef {import('./lib/index.js').Proxy} Proxy
*/

/** @type {WeakMap<Node, Proxy>} */
const cache = new WeakMap()

/**
* @param {Node} node
* Create a proxy of `node` that acts like the original tree upon reading, but
* each proxied node has a reference to its parent node.
* @returns {Proxy}
* Proxy of `node`.
*/
export function parents(node) {
return wrapNode(node, null)
}

/**
* @param {Node} node
* Node to wrap.
* @param {Parent|null} parent
* Parent of `node`.
* @returns {Proxy}
* Proxy of `node`.
*/
function wrapNode(node, parent) {
const entry = cache.get(node)

if (entry) {
return entry
}

/** @type {Proxy} */
const proxy = {}
/** @type {string} */
let key

for (key in node) {
if (key !== 'children') {
// @ts-expect-error: indexable.
proxy[key] = node[key]
}
}

Object.defineProperty(proxy, 'node', {
writable: true,
configurable: true,
value: node
})

Object.defineProperty(proxy, 'parent', {
configurable: true,
get: getParent,
set: setParent
})

if ('children' in node) {
Object.defineProperty(proxy, 'children', {
enumerable: true,
configurable: true,
get: getChildren
})
}

cache.set(node, proxy)

return proxy

/**
* Get the `parent` reference of a proxied node.
*/
function getParent() {
return parent
}

/**
* Set the `parent` reference of a proxied node.
*
* @param {Parent} newParent
*/
function setParent(newParent) {
parent = newParent
}

/**
* Get the wrapped children of a proxied node.
*/
function getChildren() {
// @ts-expect-error `node` is a parent.
return node.children.map((/** @type {Node} */ c) => wrapNode(c, proxy))
}
}
export {parents} from './lib/index.js'
103 changes: 103 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/**
* @typedef {import('unist').Parent} Parent
* @typedef {import('unist').Node} Node
*
* @typedef ProxyFields
* @property {Parent|null} parent
* Parent link (or `null` for the root).
* @property {Node} node
* Link to the original node
*
* @typedef {Node & ProxyFields} Proxy
* Proxied node
*/

/** @type {WeakMap<Node, Proxy>} */
const cache = new WeakMap()

/**
* @param {Node} node
* Create a proxy of `node` that acts like the original tree upon reading, but
* each proxied node has a reference to its parent node.
* @returns {Proxy}
* Proxy of `node`.
*/
export function parents(node) {
return wrapNode(node, null)
}

/**
* @param {Node} node
* Node to wrap.
* @param {Parent|null} parent
* Parent of `node`.
* @returns {Proxy}
* Proxy of `node`.
*/
function wrapNode(node, parent) {
const entry = cache.get(node)

if (entry) {
return entry
}

/** @type {Proxy} */
const proxy = {}
/** @type {string} */
let key

for (key in node) {
if (key !== 'children') {
// @ts-expect-error: indexable.
proxy[key] = node[key]
}
}

Object.defineProperty(proxy, 'node', {
writable: true,
configurable: true,
value: node
})

Object.defineProperty(proxy, 'parent', {
configurable: true,
get: getParent,
set: setParent
})

if ('children' in node) {
Object.defineProperty(proxy, 'children', {
enumerable: true,
configurable: true,
get: getChildren
})
}

cache.set(node, proxy)

return proxy

/**
* Get the `parent` reference of a proxied node.
*/
function getParent() {
return parent
}

/**
* Set the `parent` reference of a proxied node.
*
* @param {Parent} newParent
*/
function setParent(newParent) {
parent = newParent
}

/**
* Get the wrapped children of a proxied node.
*/
function getChildren() {
// @ts-expect-error `node` is a parent.
return node.children.map((/** @type {Node} */ c) => wrapNode(c, proxy))
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"main": "index.js",
"types": "index.d.ts",
"files": [
"lib/",
"index.d.ts",
"index.js"
],
Expand Down

0 comments on commit dc17b1d

Please sign in to comment.