GithubHelp home page GithubHelp logo

webreflection / augmentor Goto Github PK

View Code? Open in Web Editor NEW
134.0 134.0 7.0 226 KB

Extensible, general purpose, React like hooks for the masses.

Home Page: https://medium.com/@WebReflection/demystifying-hooks-f55ad885609f

License: ISC License

JavaScript 79.07% HTML 20.93%

augmentor's Introduction

webreflection

WebReflection Ltd

augmentor's People

Contributors

greenkeeper[bot] avatar webreflection avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

augmentor's Issues

An in-range update of rollup is breaking the build 🚨

The devDependency rollup was updated from 1.9.2 to 1.9.3.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

rollup is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details

Release Notes for v1.9.3

2019-04-10

Bug Fixes

  • Simplify return expressions that are evaluated before the surrounding function is bound (#2803)

Pull Requests

  • #2803: Handle out-of-order binding of identifiers to improve tree-shaking (@lukastaegert)
Commits

The new version differs by 3 commits.

  • 516a06d 1.9.3
  • a5526ea Update changelog
  • c3d73ff Handle out-of-order binding of identifiers to improve tree-shaking (#2803)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Nested context providers don't restore previous context value

Nested context providers don't restore previous context value after executing.

import { augmentor, createContext, useContext } from 'augmentor';

const TestContext = createContext();

const RootProvider = augmentor(() => {
  TestContext.provide("hello world");
  ChildProvider();
  Consume();
});

const ChildProvider = augmentor(() => {
  TestContext.provide("last update wins");
  Consume();
});

const Consume = augmentor(() => {
  const message = useContext(TestContext);
  console.log(message);
});

RootProvider();

Actual Output

last hello wins 
last hello wins

Expected output

last hello wins 
hello world

Changing the root to this:

const RootProvider = augmentor(() => {
  TestContext.provide("hello world");
  Consume();
  ChildProvider();
  Consume();
});

Produces output I truly wouldn't expect:

hello world 
last hello wins 
last hello wins 
last hello wins 

An extra invocation, no?

Extending hooks - third party hook libs

I'm having a hard time getting a standalone redux hook to work.
Some code below. I think it might be a bug.

I know I put swiss-element but it mostly exports all the hooks from augmentor besides a small adjustment of useEffect.

The browser error that is shown:

screen shot 2019-01-27 at 10 26 02 pm

The now variable is null. Seems to be caused by duplicate code of a separate import of augmentor in the main library and another in the standalone redux hook library.

import {
  useEffect,
  createContext as cc,
  useContext,
  useState
} from 'swiss-element';

import shallowEqual from './shallow-equal.js';

let reduxContext;
export function createContext(store) {
  reduxContext = cc();
  reduxContext.provide(store);
}

export function useSelector(selector) {
  const store = useContext(reduxContext);
  const { getState } = store;
  const [result, setResult] = useState(selector(getState()));

  return useEffect(
    store.subscribe(() => {
      const nextResult = selector(getState());
      if (shallowEqual(nextResult, result)) return;
      setResult(nextResult);
    }),
  );
}

export function useActionCreator(actionCreator) {
  const { dispatch } = useContext(reduxContext);
  return (...args) => dispatch(actionCreator(...args));
}

comparison to haunted?

Both this and haunted are listed on the hyperHTML page...

Seems haunted has context already... can someone please explain some of the pros/cons to using augmentor vs. haunted?

Why would values be undefined in createEffect?

I'm building a moderately sized app using neverland, and am encountering an error that seems to be triggered by the augmentor code.

Specifically, the use of useEffect sometimes triggers the following error:

index.js:192 Uncaught TypeError: Cannot read property '0' of undefined
    at different (index.js:192)
    at Array.some (<anonymous>)
    at index.js:123
    at SelectSubField (DefaultCollection_Doc_SelectSubField.js:60)
    at SubField (DefaultCollection_Doc_SequenceField.js:193)
    at DefaultCollection_Doc_SequenceField.js:251
    at Array.map (<anonymous>)
    at DefaultCollection_Doc_SequenceField.js:247
    at Array.map (<anonymous>)
    at Element (DefaultCollection_Doc_SequenceField.js:244)

Which I have traced back to the createEffect function in augmentor:

const createEffect = asy => (effect, guards) => {
  const i = state.i++;
  const {hook, after, stack, length} = state;
  if (i < length) {
    const info = stack[i];
    const {update, values, stop} = info;
    if (!guards || guards.some(different, values)) {
      // ^^^ Error is triggered on the previous line because 'values' is undefined. ^^^
      // ...

It will be quite a lot of work to create a minimal example so before I do I thought I would ask: can you think of any reason why values would be undefined?

`contextual` does not clean up via `dropEffect`

let {contextual, augmentor, useEffect, dropEffect} = await import('augmentor')
  let f = contextual(() => {
    useEffect(() => {
      console.log('in')
      return () => {
        console.log('out')
      }
    })
  })
  f()
  await time(10)
  dropEffect(f)

As we see, 'out' is never logged. Although that works fine with just augmentor entry.

useReducer accumulator stale if initial function ref is reused

import { neverland as $, html, render, useReducer, useEffect } from 'neverland'

const app = $(() => {
  const [count, inc] = useReducer(c => c + 1, 0)
  
  useEffect(() => {
    // inc does not work after first call, because of stale accumulator
    // since implementation relies on `useState`
    const id = setInterval(inc, 500)
    return () => clearInterval(id)
  }, [])
  
  return html`<h1>The count is ${count}</h1>`
})

render(document.body, app)

live example

It might make sense to treat useReducer as the base implementation and have useState call useReducer.. πŸ€”

This is what preact does.

Also as a side note, have you considered making useState/useReducer return a consistent function reference, like React's/Preact's hook implementations?

Asynchronous functions lose effects

import a from 'augmentor'
let f1 = a.augmentor(async () => {
  let [x, setx] = a.useState(0);
  console.log(x)
  await '';
  a.useEffect(() => {
    setx(1)
  }, [])
});

Function isn't updated here. Is that by design?

useState/render issue with arrays.

Example: https://codepen.io/ripter/pen/LKpbgd?editors=0011

const [history, setHistory] = useState([0]); with setHistory(history.concat([i])); triggers the re-render as expected. The console.logs show the data has been updated; but the html is rendered as if the data were empty.

Click the button in the example to see the list disappear instead of rendering the new item. And the button does not update to show the new value of i.

Context is lost

If we call a function with defined context, the handler loses it.

import { augmentor } from 'augmentor'
  let fn = augmentor(function () { console.log(this) })
  fn.call({ x: 1 })

// null

Is that expected?

Can async functions be augmented ?

Hello,
I have a question about augmented async functions

augmentor(() => {
    myAsyncFunction().then(() => {});
})

myAsyncFunction containing useState hook

useState lazy init

According to the useState docs, it can be initialized with the function.

let [value, setValue] = useState(() => initialValue)
// typeof value === 'function'
// but must be initialValue

Augmentor doesn't seem to support that for now.

Sandbox

useEffect is called once per frame

import augment, { useEffect } from 'augmentor'

let f = augment(() => useEffect(() => console.log('augmentor')))
f()
f()
f()

From this example, the useEffect is called only once.
React calls useEffect any time render is called (sandbox).

Is that so by design?

An in-range update of uglify-js is breaking the build 🚨


🚨 Reminder! Less than one month left to migrate your repositories over to Snyk before Greenkeeper says goodbye on June 3rd! πŸ’œ πŸššπŸ’¨ πŸ’š

Find out how to migrate to Snyk at greenkeeper.io


The devDependency uglify-js was updated from 3.9.2 to 3.9.3.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

uglify-js is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details

Release Notes for v3.9.3

Β 

Commits

The new version differs by 35 commits.

  • 30ed8f5 v3.9.3
  • dc9e7cd suppress ufuzz false positives (#3893)
  • 76f40e2 fix corner case in collapse_vars (#3892)
  • 8024f7f fix corner case in ie8 (#3890)
  • eb7fa25 fix corner case in evaluate (#3888)
  • ee7647d fix corner case in collapse_vars (#3885)
  • bd2f53b fix corner case in evaluate (#3883)
  • e8a7956 fix corner case in reduce_vars (#3881)
  • 2b24dc2 fix corner cases in evaluate & reduce_vars (#3879)
  • 35cc5aa extend --reduce-test to cover minify() bugs (#3876)
  • c1dd49e fix corner case in comparisons (#3877)
  • c76ee4b enhance if_return (#3875)
  • e23bf48 enhance evaluate & reduce_vars (#3873)
  • 7e0ad23 retain @__PURE__ call when return value is used (#3874)
  • 63adfb1 fix corner case in hoist_props (#3872)

There are 35 commits in total.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Immediately invoked setState from useEffect/useLayoutEffect causes Maximum call stack size exceeded

Apologies if this issue submission is lacking details, but I came across this while experimenting with various hooks from React land last night.

From what I can tell it seems like hooks implemented in the following style cause augmentor to enter into some race condition.

import augmentor, {useLayoutEffect, useState} from 'https://unpkg.com/augmentor?module'

const a = augmentor(test)
a()

function test() {
  const elapsed = useRaf(5000, 1000) // πŸ”₯ will lock your browser!
  console.log(elapsed)
}

function useRaf (ms, delay) {
  const [elapsed, set] = useState(0)

  useLayoutEffect(() => {
    let raf, timerStop, start

    const onFrame = () => {
      const time = Math.min(1, (Date.now() - start) / ms)
      set(time)
      loop()
    }
    const loop = () => {
      raf = requestAnimationFrame(onFrame)
    }
    const onStart = () => {
      timerStop = setTimeout(() => {
        cancelAnimationFrame(raf)
        set(1)
      }, ms)
      start = Date.now()
      loop()
    }
    const timerDelay = setTimeout(onStart, delay)

    return () => {
      clearTimeout(timerStop)
      clearTimeout(timerDelay)
      cancelAnimationFrame(raf)
    };
  }, [ms, delay])

  return elapsed
}

With the limited knowledge I have in this space, it seems as though there are two possible issues here:

  1. useEffect/useLayoutEffect seem to be triggered regardless of whether the second argument ref is the same
  2. calling the update function from useState immediately causes augmentor to hit some race condition

For reference, here's how the above behaves in React https://codesandbox.io/s/r5rmkr933m

Domtagger in readme

Readme contains wrong package info.

Include via:

CDN as global utility, via unpkg.com/domtagger
CJS via const domtagger = require('domtagger')
ESM via import domtagger from 'domtagger'
ESM CDN via import domtagger from 'https://unpkg.com/domtagger?module'

createContext initial value

Could createContext() already take an initial argument?
Would be a bit cleaner if it would be possible.

const ctx = createContext(store)

instead of

const ctx = createContext()
ctx.provide(store)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.