~evanj/wigly

26a59d35a84930cd319f9c387009e013531640cb — Evan M Jones 2 years ago f84a746
better outputs w/ gcc (@export)
4 files changed, 152 insertions(+), 152 deletions(-)

M example/main.jsx
M package.json
D src/entry.js
M src/main.js
M example/main.jsx => example/main.jsx +1 -1
@@ 1,5 1,5 @@
// @jsx h
import { h, render, useState, useEffect } from "../dist/main.js";
import { h, render, useState, useEffect } from "../";

let Test = ({ other }) => {
  let [msg, setMsg] = useState("wow!");

M package.json => package.json +7 -2
@@ 1,10 1,15 @@
{
  "name": "wigly",
  "version": "0.3.0",
  "main": "dist/wigly.es5.js",
  "scripts": {
    "example": "parcel example/index.html",
    "build": "npm run build:gcc && npm run build:gzip",
    "build:gcc": "java -jar ./node_modules/google-closure-compiler/compiler.jar --module_resolution WEBPACK --assume_function_wrapper --isolation_mode IIFE --use_types_for_optimization --language_in ECMASCRIPT_NEXT --language_out ECMASCRIPT_2015 --externs externs/superfine.js --generate_exports --export_local_property_definitions --compilation_level ADVANCED --js_output_file=dist/main.js 'src/**.js'",
    "build": "npm run build:clean && npm run build:gcc:es5 && npm run build:gcc:es6 && npm run build:prepend:es5 && npm run build:prepend:es6 && npm run build:gzip",
    "build:clean": "rm -rf dist",
    "build:gcc:es5": "java -jar ./node_modules/google-closure-compiler/compiler.jar --module_resolution WEBPACK --assume_function_wrapper --isolation_mode IIFE --use_types_for_optimization --language_in ECMASCRIPT_NEXT --language_out ECMASCRIPT5 --externs externs/superfine.js --generate_exports --export_local_property_definitions --compilation_level ADVANCED --js_output_file=dist/wigly.es5.js 'src/**.js'",
    "build:gcc:es6": "java -jar ./node_modules/google-closure-compiler/compiler.jar --module_resolution WEBPACK --assume_function_wrapper --isolation_mode IIFE --use_types_for_optimization --language_in ECMASCRIPT_NEXT --language_out ECMASCRIPT_2015 --externs externs/superfine.js --generate_exports --export_local_property_definitions --compilation_level ADVANCED --js_output_file=dist/wigly.es6.js 'src/**.js'",
    "build:prepend:es5": "awk '{print $0}' node_modules/superfine/dist/superfine.js dist/wigly.es5.js > dist/wigly.es5.js.tmp && mv dist/wigly.es5.js.tmp dist/wigly.es5.js",
    "build:prepend:es6": "awk '{print $0}' node_modules/superfine/dist/superfine.js dist/wigly.es6.js > dist/wigly.es6.js.tmp && mv dist/wigly.es6.js.tmp dist/wigly.es6.js",
    "build:gzip": "gzip dist/* -k -f",
    "size": "wc -c dist/*"
  },

D src/entry.js => src/entry.js +0 -14
@@ 1,14 0,0 @@
import { h, render, useState, useEffect } from "./main";

let pkg = {
  ["h"]: h,
  ["render"]: render,
  ["useState"]: useState,
  ["useEffect"]: useEffect
};

if (typeof module !== "undefined") {
  module["exports"] = pkg;
} else {
  window["wigly"] = pkg;
}

M src/main.js => src/main.js +144 -135
@@ 1,8 1,4 @@
/**
 * TYPES
 */

/**
 * @record
 */
function ComponentEnvironment() {}


@@ 64,164 60,177 @@ Effect.prototype.last;
Effect.prototype.cb;

/**
 * VARS
 * @const
 */

let NOOP = () => {};

let actualUseState = NOOP;
let actualUseEffect = NOOP;
let getSeedState = NOOP;
let parentCallback = NOOP;

/**
 * FUNCTIONS
 * @export
 */
let wigly = {
  /**
   * @export
   */
  h: (type, props, ...rest) => {
    if (typeof type !== "function") {
      return superfine.h(type, props, ...rest);
    }

let h = (type, props, ...rest) => {
  if (typeof type !== "function") {
    return superfine.h(type, props, ...rest);
  }
    let originalGetSeedState = getSeedState;
    let originalParentCallback = parentCallback;

  let originalGetSeedState = getSeedState;
  let originalParentCallback = parentCallback;
    let stateCount = 0;
    let effectCount = 0;

  let stateCount = 0;
  let effectCount = 0;
    /** @type {ComponentEnvironment} */
    let seed = originalGetSeedState(type, props) || {};
    let { isActive = true, vars = {}, effects = [], childs = [], node, lastVDOM } = seed;

  /** @type {ComponentEnvironment} */
  let seed = originalGetSeedState(type, props) || {};
  let { isActive = true, vars = {}, effects = [], childs = [], node, lastVDOM } = seed;
    let internalUseState = init => {
      let key = stateCount++;
      let value = vars[key];

  let internalUseState = init => {
    let key = stateCount++;
    let value = vars[key];
      if (value === undefined) {
        value = init;
      }

    if (value === undefined) {
      value = init;
    }
      return [
        value,
        next => {
          vars[key] = next;
          save();
          update();
        }
      ];
    };

    return [
      value,
      next => {
        vars[key] = next;
        save();
        update();
    let internalUseEffect = (f, unique) => {
      let key = effectCount++;
      /** @type {Effect} */
      let effect = { ...effects[key], f, unique };
      effects[key] = effect;
    };

    let internalGetSeedState = (find, props) => {
      for (let index in childs) {
        /** @type {ComponentEnvironment} */
        let child = childs[index];
        let key = (child.props || {}).key;
        if (child.type === find && key === (props || {}).key) {
          return { ...child, isActive };
        }
      }
    ];
  };

  let internalUseEffect = (f, unique) => {
    let key = effectCount++;
    /** @type {Effect} */
    let effect = { ...effects[key], f, unique };
    effects[key] = effect;
  };

  let internalGetSeedState = (find, props) => {
    for (let index in childs) {
      /** @type {ComponentEnvironment} */
      let child = childs[index];
      let key = (child.props || {}).key;
      if (child.type === find && key === (props || {}).key) {
        return { ...child, isActive };
    };

    // TODO: it's bogus.
    let internalParentCallback = data => {
      if (!data) {
        childs = [];
        return;
      }
      childs.push(data);
    };

    return work();

    function work() {
      actualUseState = internalUseState;
      actualUseEffect = internalUseEffect;
      getSeedState = internalGetSeedState;
      parentCallback = internalParentCallback;

      /** @type {SuperFineArgs} */
      let args = { props };

      /** @type {VDOM} */
      let res = type(args);

      stateCount = 0;
      effectCount = 0;
      actualUseState = NOOP;
      actualUseEffect = NOOP;
      getSeedState = originalGetSeedState;
      parentCallback = originalParentCallback;

      /** @type {VDOM} */
      let vdom = { ...res, props: { ...res.props, oncreate, onupdate, onremove, ondestroy } };

      return (lastVDOM = vdom);
    }
  };

  // TODO: it's bogus.
  let internalParentCallback = data => {
    if (!data) {
      childs = [];
      return;
    function oncreate(el) {
      node = el;
      save();
      callEffects();
    }
    childs.push(data);
  };

  return work();

  function work() {
    actualUseState = internalUseState;
    actualUseEffect = internalUseEffect;
    getSeedState = internalGetSeedState;
    parentCallback = internalParentCallback;

    /** @type {SuperFineArgs} */
    let args = { props };

    /** @type {VDOM} */
    let res = type(args);

    stateCount = 0;
    effectCount = 0;
    actualUseState = NOOP;
    actualUseEffect = NOOP;
    getSeedState = originalGetSeedState;
    parentCallback = originalParentCallback;

    /** @type {VDOM} */
    let vdom = { ...res, props: { ...res.props, oncreate, onupdate, onremove, ondestroy } };

    return (lastVDOM = vdom);
  }

  function oncreate(el) {
    node = el;
    save();
    callEffects();
  }

  function onupdate() {
    callEffects();
  }

  function onremove(_, remove) {
    isActive = false;
    callEffects();
    update();
    remove();
    reset();
  }

  function ondestroy() {
    callEffects();
    reset();
  }

  function save() {
    /** @type {ComponentEnvironment} */
    let env = { type, props, vars, childs, node, lastVDOM, effects };
    originalParentCallback(env);
  }

  function reset() {
    originalParentCallback();
  }
    function onupdate() {
      callEffects();
    }

  function update() {
    superfine.patch(lastVDOM, work(), node);
  }
    function onremove(_, remove) {
      isActive = false;
      callEffects();
      update();
      remove();
      reset();
    }

  function callEffects() {
    for (let key in effects) {
      /** @type {Effect} */
      let value = effects[key];
      let { f, unique, last, cb } = value;
      let serialized = (Array.isArray(unique) ? unique : [unique]).join();
    function ondestroy() {
      callEffects();
      reset();
    }

    function save() {
      /** @type {ComponentEnvironment} */
      let env = { type, props, vars, childs, node, lastVDOM, effects };
      originalParentCallback(env);
    }

      if (unique === undefined || last !== serialized || !isActive) {
        cb && cb();
    function reset() {
      originalParentCallback();
    }

    function update() {
      superfine.patch(lastVDOM, work(), node);
    }

        if (isActive) {
          effects[key].cb = f(node);
          effects[key].last = serialized;
    function callEffects() {
      for (let key in effects) {
        /** @type {Effect} */
        let value = effects[key];
        let { f, unique, last, cb } = value;
        let serialized = (Array.isArray(unique) ? unique : [unique]).join();

        if (unique === undefined || last !== serialized || !isActive) {
          cb && cb();

          if (isActive) {
            effects[key].cb = f(node);
            effects[key].last = serialized;
          }
        }
      }
    }
  }
  },

  /**
   * @export
   */
  render: (app, el) => superfine.patch(null, app, el),

  /**
   * @export
   */
  useState: val => actualUseState(val),

  /**
   * @export
   */
  useEffect: (f, unique) => actualUseEffect(f, unique)
};

let render = (app, el) => superfine.patch(null, app, el);
let useState = val => actualUseState(val);
let useEffect = (f, unique) => actualUseEffect(f, unique);

export { h, render, useState, useEffect };