Full Code of pomber/didact for AI

master bb72345b2300 cached
4 files
12.7 KB
3.2k tokens
15 symbols
1 requests
Download .txt
Repository: pomber/didact
Branch: master
Commit: bb72345b2300
Files: 4
Total size: 12.7 KB

Directory structure:
gitextract_3ia6oj2f/

├── .prettierrc
├── didact.js
├── package.json
└── readme.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .prettierrc
================================================
{
  "semi": false,
  "printWidth": 52,
  "trailingComma": "es5"
}


================================================
FILE: didact.js
================================================
function createElement(type, props, ...children) {
  return {
    type,
    props: {
      ...props,
      children: children.map(child =>
        typeof child === "object"
          ? child
          : createTextElement(child)
      ),
    },
  }
}

function createTextElement(text) {
  return {
    type: "TEXT_ELEMENT",
    props: {
      nodeValue: text,
      children: [],
    },
  }
}

function createDom(fiber) {
  const dom =
    fiber.type == "TEXT_ELEMENT"
      ? document.createTextNode("")
      : document.createElement(fiber.type)

  updateDom(dom, {}, fiber.props)

  return dom
}

const isEvent = key => key.startsWith("on")
const isProperty = key =>
  key !== "children" && !isEvent(key)
const isNew = (prev, next) => key =>
  prev[key] !== next[key]
const isGone = (prev, next) => key => !(key in next)
function updateDom(dom, prevProps, nextProps) {
  //Remove old or changed event listeners
  Object.keys(prevProps)
    .filter(isEvent)
    .filter(
      key =>
        !(key in nextProps) ||
        isNew(prevProps, nextProps)(key)
    )
    .forEach(name => {
      const eventType = name
        .toLowerCase()
        .substring(2)
      dom.removeEventListener(
        eventType,
        prevProps[name]
      )
    })

  // Remove old properties
  Object.keys(prevProps)
    .filter(isProperty)
    .filter(isGone(prevProps, nextProps))
    .forEach(name => {
      dom[name] = ""
    })

  // Set new or changed properties
  Object.keys(nextProps)
    .filter(isProperty)
    .filter(isNew(prevProps, nextProps))
    .forEach(name => {
      dom[name] = nextProps[name]
    })

  // Add event listeners
  Object.keys(nextProps)
    .filter(isEvent)
    .filter(isNew(prevProps, nextProps))
    .forEach(name => {
      const eventType = name
        .toLowerCase()
        .substring(2)
      dom.addEventListener(
        eventType,
        nextProps[name]
      )
    })
}

function commitRoot() {
  deletions.forEach(commitWork)
  commitWork(wipRoot.child)
  currentRoot = wipRoot
  wipRoot = null
}

function commitWork(fiber) {
  if (!fiber) {
    return
  }

  let domParentFiber = fiber.parent
  while (!domParentFiber.dom) {
    domParentFiber = domParentFiber.parent
  }
  const domParent = domParentFiber.dom

  if (
    fiber.effectTag === "PLACEMENT" &&
    fiber.dom != null
  ) {
    domParent.appendChild(fiber.dom)
  } else if (
    fiber.effectTag === "UPDATE" &&
    fiber.dom != null
  ) {
    updateDom(
      fiber.dom,
      fiber.alternate.props,
      fiber.props
    )
  } else if (fiber.effectTag === "DELETION") {
    commitDeletion(fiber, domParent)
  }

  commitWork(fiber.child)
  commitWork(fiber.sibling)
}

function commitDeletion(fiber, domParent) {
  if (fiber.dom) {
    domParent.removeChild(fiber.dom)
  } else {
    commitDeletion(fiber.child, domParent)
  }
}

function render(element, container) {
  wipRoot = {
    dom: container,
    props: {
      children: [element],
    },
    alternate: currentRoot,
  }
  deletions = []
  nextUnitOfWork = wipRoot
}

let nextUnitOfWork = null
let currentRoot = null
let wipRoot = null
let deletions = null

function workLoop(deadline) {
  let shouldYield = false
  while (nextUnitOfWork && !shouldYield) {
    nextUnitOfWork = performUnitOfWork(
      nextUnitOfWork
    )
    shouldYield = deadline.timeRemaining() < 1
  }

  if (!nextUnitOfWork && wipRoot) {
    commitRoot()
  }

  requestIdleCallback(workLoop)
}

requestIdleCallback(workLoop)

function performUnitOfWork(fiber) {
  const isFunctionComponent =
    fiber.type instanceof Function
  if (isFunctionComponent) {
    updateFunctionComponent(fiber)
  } else {
    updateHostComponent(fiber)
  }
  if (fiber.child) {
    return fiber.child
  }
  let nextFiber = fiber
  while (nextFiber) {
    if (nextFiber.sibling) {
      return nextFiber.sibling
    }
    nextFiber = nextFiber.parent
  }
}

let wipFiber = null
let hookIndex = null

function updateFunctionComponent(fiber) {
  wipFiber = fiber
  hookIndex = 0
  wipFiber.hooks = []
  const children = [fiber.type(fiber.props)]
  reconcileChildren(fiber, children)
}

function useState(initial) {
  const oldHook =
    wipFiber.alternate &&
    wipFiber.alternate.hooks &&
    wipFiber.alternate.hooks[hookIndex]
  const hook = {
    state: oldHook ? oldHook.state : initial,
    queue: [],
  }

  const actions = oldHook ? oldHook.queue : []
  actions.forEach(action => {
    hook.state = action(hook.state)
  })

  const setState = action => {
    hook.queue.push(action)
    wipRoot = {
      dom: currentRoot.dom,
      props: currentRoot.props,
      alternate: currentRoot,
    }
    nextUnitOfWork = wipRoot
    deletions = []
  }

  wipFiber.hooks.push(hook)
  hookIndex++
  return [hook.state, setState]
}

function updateHostComponent(fiber) {
  if (!fiber.dom) {
    fiber.dom = createDom(fiber)
  }
  reconcileChildren(fiber, fiber.props.children)
}

function reconcileChildren(wipFiber, elements) {
  let index = 0
  let oldFiber =
    wipFiber.alternate && wipFiber.alternate.child
  let prevSibling = null

  while (
    index < elements.length ||
    oldFiber != null
  ) {
    const element = elements[index]
    let newFiber = null

    const sameType =
      oldFiber &&
      element &&
      element.type == oldFiber.type

    if (sameType) {
      newFiber = {
        type: oldFiber.type,
        props: element.props,
        dom: oldFiber.dom,
        parent: wipFiber,
        alternate: oldFiber,
        effectTag: "UPDATE",
      }
    }
    if (element && !sameType) {
      newFiber = {
        type: element.type,
        props: element.props,
        dom: null,
        parent: wipFiber,
        alternate: null,
        effectTag: "PLACEMENT",
      }
    }
    if (oldFiber && !sameType) {
      oldFiber.effectTag = "DELETION"
      deletions.push(oldFiber)
    }

    if (oldFiber) {
      oldFiber = oldFiber.sibling
    }

    if (index === 0) {
      wipFiber.child = newFiber
    } else if (element) {
      prevSibling.sibling = newFiber
    }

    prevSibling = newFiber
    index++
  }
}

const Didact = {
  createElement,
  render,
  useState,
}

/** @jsx Didact.createElement */
function Counter() {
  const [state, setState] = Didact.useState(1)
  return (
    <h1 onClick={() => setState(c => c + 1)}>
      Count: {state}
    </h1>
  )
}
const element = <Counter />
const container = document.getElementById("root")
Didact.render(element, container)


================================================
FILE: package.json
================================================
{
  "name": "didact",
  "version": "3.0.0",
  "description": "A didactic alternative to React",
  "license": "MIT",
  "repository": "pomber/didact",
  "author": "pomber",
  "main": "didact.js",
  "keywords": [
    "react"
  ]
}


================================================
FILE: readme.md
================================================
<p align="center"><img src="https://cloud.githubusercontent.com/assets/1911623/26426031/5176c348-40ad-11e7-9f1a-1e2f8840b562.jpeg"></p>

# Didact

#### A DIY guide to build your own React

This repository goes together with a [series of posts](https://medium.com/hexacta-engineering/didact-learning-how-react-works-by-building-it-from-scratch-51007984e5c5) that explains how to build React from scratch step by step. **You can jump straight to [the last post](https://pomb.us/build-your-own-react) which is self-contained and includes everything.**

| Blog Post                                                                                                                                       |                         Code sample                          |                                                                                                                                    Commits                                                                                                                                    |                                                       Other languages                                                       |
| ----------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------: |
| [Introduction](https://medium.com/hexacta-engineering/didact-learning-how-react-works-by-building-it-from-scratch-51007984e5c5)                        |                                                              |                                                                                                                                                                                                                                                                               |                                                                                                                             |
| [Rendering DOM elements](https://medium.com/hexacta-engineering/didact-rendering-dom-elements-91c9aa08323b)                                            | [codepen](https://codepen.io/pomber/pen/eWbwBq?editors=0010) |                                                                                           [diff](https://github.com/hexacta/didact/commit/fc4d360d91a1e68f0442d39dbce5b9cca5a08f24)                                                                                           |               [中文](https://github.com/chinanf-boy/didact-explain#1-%E6%B8%B2%E6%9F%93dom%E5%85%83%E7%B4%A0)               |
| [Element creation and JSX](https://medium.com/hexacta-engineering/didact-element-creation-and-jsx-d05171c55c56)                                        | [codepen](https://codepen.io/pomber/pen/xdmoWE?editors=0010) |                                                                                           [diff](https://github.com/hexacta/didact/commit/15010f8e7b8b54841d1e2dd9eacf7b3c06b1a24b)                                                                                           |          [中文](https://github.com/chinanf-boy/didact-explain#2-%E5%85%83%E7%B4%A0%E5%88%9B%E5%BB%BA%E5%92%8Cjsx)           |
| [Virtual DOM and reconciliation](https://medium.com/hexacta-engineering/didact-instances-reconciliation-and-virtual-dom-9316d650f1d0)                  | [codepen](https://codepen.io/pomber/pen/WjLqYW?editors=0010) | [diff](https://github.com/hexacta/didact/commit/8eb7ffd6f5e210526fb4c274c4f60d609fe2f810) [diff](https://github.com/hexacta/didact/commit/6f5fdb7331ed77ba497fa5917d920eafe1f4c8dc) [diff](https://github.com/hexacta/didact/commit/35619a039d48171a6e6c53bd433ed049f2d718cb) | [中文](https://github.com/chinanf-boy/didact-explain#3-%E5%AE%9E%E4%BE%8B-%E5%AF%B9%E6%AF%94%E5%92%8C%E8%99%9A%E6%8B%9Fdom) |
| [Components and State](https://medium.com/hexacta-engineering/didact-components-and-state-53ab4c900e37)                                                |       [codepen](https://codepen.io/pomber/pen/RVqBrx)        |                                                                                           [diff](https://github.com/hexacta/didact/commit/2e290ff5c486b8a3f361abcbc6e36e2c21db30b8)                                                                                           |            [中文](https://github.com/chinanf-boy/didact-explain#4-%E7%BB%84%E4%BB%B6%E5%92%8C%E7%8A%B6%E6%80%81)            |
| [Fiber: Incremental reconciliation](https://medium.com/hexacta-engineering/didact-fiber-incremental-reconciliation-b2fe028dcaec) (self-contained post) |       [codepen](https://codepen.io/pomber/pen/veVOdd)        |                                              [diff](https://github.com/hexacta/didact/commit/6174a2289e69895acd8fc85abdc3aaff1ded9011) [diff](https://github.com/hexacta/didact/commit/accafb81e116a0569f8b7d70e5b233e14af999ad)                                              |             [中文](https://github.com/chinanf-boy/didact-explain#5-fibre-%E9%80%92%E5%A2%9E%E5%AF%B9%E6%AF%94)              |
| [The one with Hooks](https://pomb.us/build-your-own-react) (self-contained post)                                                                |    [codesandbox](https://codesandbox.io/s/didact-8-21ost)    |                                                                                                                                                                                                                                                                               |  [中文](https://www.tangdingblog.cn/blog/react/buildyourownreact-2020-09-22/)                                                                                                                         |

> Follow [@pomber](https://twitter.com/pomber) on twitter for updates.

## License

The MIT License (MIT)
Download .txt
gitextract_3ia6oj2f/

├── .prettierrc
├── didact.js
├── package.json
└── readme.md
Download .txt
SYMBOL INDEX (15 symbols across 1 files)

FILE: didact.js
  function createElement (line 1) | function createElement(type, props, ...children) {
  function createTextElement (line 15) | function createTextElement(text) {
  function createDom (line 25) | function createDom(fiber) {
  function updateDom (line 42) | function updateDom(dom, prevProps, nextProps) {
  function commitRoot (line 92) | function commitRoot() {
  function commitWork (line 99) | function commitWork(fiber) {
  function commitDeletion (line 132) | function commitDeletion(fiber, domParent) {
  function render (line 140) | function render(element, container) {
  function workLoop (line 157) | function workLoop(deadline) {
  function performUnitOfWork (line 175) | function performUnitOfWork(fiber) {
  function updateFunctionComponent (line 198) | function updateFunctionComponent(fiber) {
  function useState (line 206) | function useState(initial) {
  function updateHostComponent (line 237) | function updateHostComponent(fiber) {
  function reconcileChildren (line 244) | function reconcileChildren(wipFiber, elements) {
  function Counter (line 309) | function Counter() {
Condensed preview — 4 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (14K chars).
[
  {
    "path": ".prettierrc",
    "chars": 66,
    "preview": "{\n  \"semi\": false,\n  \"printWidth\": 52,\n  \"trailingComma\": \"es5\"\n}\n"
  },
  {
    "path": "didact.js",
    "chars": 6431,
    "preview": "function createElement(type, props, ...children) {\n  return {\n    type,\n    props: {\n      ...props,\n      children: chi"
  },
  {
    "path": "package.json",
    "chars": 228,
    "preview": "{\n  \"name\": \"didact\",\n  \"version\": \"3.0.0\",\n  \"description\": \"A didactic alternative to React\",\n  \"license\": \"MIT\",\n  \"r"
  },
  {
    "path": "readme.md",
    "chars": 6242,
    "preview": "<p align=\"center\"><img src=\"https://cloud.githubusercontent.com/assets/1911623/26426031/5176c348-40ad-11e7-9f1a-1e2f8840"
  }
]

About this extraction

This page contains the full source code of the pomber/didact GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 4 files (12.7 KB), approximately 3.2k tokens, and a symbol index with 15 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!