Giter Site home page Giter Site logo

giusepperaso / structura.js Goto Github PK

View Code? Open in Web Editor NEW
404.0 2.0 6.0 3.79 MB

A very fast and lightweight Typescript library to create immutable states with a mutable syntax

Home Page: https://giusepperaso.github.io/structura.js/

License: MIT License

HTML 0.25% TypeScript 99.75%
immutability state structural-sharing javascript typescript

structura.js's People

Contributors

dependabot[bot] avatar giusepperaso avatar trevorsayre 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

structura.js's Issues

Safe produce with function parameter

Hi thank you very much for the library.

I wanted to raise an issue which is not really with the library, but with typescript, yet I encountered it using it and got a workaround for myself, so decided to share it in case it could help some users or in case it could be adjusted for in the library.

The problem is that if I write const myVal = ((f: () => void) => f())(() => 3) Ts will happily assign type void to myVal.

So here's what it looks like when I tried to curry safeProduceWithPatches:

const f =
  <T>(x: T) =>
  (f: (x: UnFreeze<T>) => void) =>
    safeProduceWithPatches(x, f)
f(s)((s) => (s.hey = "hi")) // no TS error

So I lose the safety. Notice that here I thought I'd only limit f to be the non-returning forms. If I write instead: (f: (x: UnFreeze<T>) => void | T) then it works fine again and produces the correct error on the last line.
Going in this direction (f: (x: UnFreeze<T>) => void | undefined) also produces the error correctly and accomplishes what I intended.

Add to NPM

Would be useful to be able to use this package via NPM.
Thanks!

Does castDraft in immer library exist in this library?

type Todo = {readonly done: boolean}

type State = {
    readonly finishedTodos: readonly Todo[]
    readonly unfinishedTodos: readonly Todo[]
}

function markAllFinished(state: State) {
    produce(state, draft => {
        draft.finishedTodos = state.unfinishedTodos // => The type 'readonly Todo[]' is 'readonly' and cannot be assigned to the mutable type '{ done: boolean; }[]'
    })
}

in Immer
draft.finishedTodos = castDraft(state.unfinishedTodos) // => will make the error disappear.

This library is very interesting in that it improves the immer speed problem.

Equivalent of immers Immutable type

hi :)

I wanted to try if my app would run faster with structura.js than it does right now with immer.

My immer code looks like this:

export const convertPatchesToDiff = <TState extends {}>(
  initialState: Immutable<TState>,
  transactions: Patch[][],
  derivateFn: (state: TState) => void
) => {
  const [initialDerivedState, , initialRevertDerivation] = produceWithPatches(
    initialState,
    derivateFn
  );
  // ...

I tried to find the equivalent for Immutable from immer.js.

I felt a little bit los as the index.d.ts files doesn't have many comments and most variables are named T or Q.
But I guess that's fine given the early state of strucura.js.

I tried Freeze:

export const convertPatchesToDiff = <TState extends {}>(
  initialState: Freeze<TState>,
  transactions: Patch[][],
  derivateFn: (state: TState) => void
) => {
const [initialDerivedState, , initialRevertDerivation] = produceWithPatches(
    initialState,
    derivateFn
  );
  // ...

However this gives me the following type error:

Argument of type '(state: TState) => void' is not assignable to parameter of type 'Producer<Freeze<TState>, void>'.
  Types of parameters 'state' and 'draft' are incompatible.
    Type 'UnFreeze<Freeze<TState>>' is not assignable to type 'TState'.

Can you please let me know if there is already an equivalent of immers Immutable type?

Problem with circular data

The following code:

import { produce } from "structurajs";

class HbNode {
  constructor(data, parent) {
    this.parent = parent;
    this.children = [];
    Object.assign(this, data);
  }
  addChild(data, index) {
    const child = new HbNode(data, this);
    this.children.splice(index, 0, child);
  }
}

const root = new HbNode(
  {
    id: "0",
    name: "root",
  },
);

const children = [
  {
    id: "1",
    name: "child1",
  },
  {
    id: "2",
    name: "child2",
  },
];

const rootDraft = produce(root, (draft) => {
  for (const [i, value] of children.entries()) {
    draft.addChild(value, i);
  }
});

console.log(JSON.stringify(rootDraft, null, 4));

will throw

file:///D:/tmp/structure-test/node_modules/structurajs/dist/index.js:552
    return Reflect.ownKeys(i);
                   ^

RangeError: Maximum call stack size exceeded
    at Reflect.ownKeys (<anonymous>)
    at ne.ownKeys (file:///D:/tmp/structure-test/node_modules/structurajs/dist/index.js:552:20)
    at Reflect.ownKeys (<anonymous>)
    at ne.ownKeys (file:///D:/tmp/structure-test/node_modules/structurajs/dist/index.js:552:20)
    at Reflect.ownKeys (<anonymous>)
    at ne.ownKeys (file:///D:/tmp/structure-test/node_modules/structurajs/dist/index.js:552:20)
    at Reflect.ownKeys (<anonymous>)
    at ne.ownKeys (file:///D:/tmp/structure-test/node_modules/structurajs/dist/index.js:552:20)
    at Reflect.ownKeys (<anonymous>)
    at ne.ownKeys (file:///D:/tmp/structure-test/node_modules/structurajs/dist/index.js:552:20)

due to circular data structure. Is structurejs intended to support this kind of circular data?

Compile error with cloneAndMutateFunc use for creation of a Store

I have the following Typescript types and classes:


import { nanoid } from 'nanoid'

import { immerable } from 'immer'

export type TID = string | number

export type TAge = {
   id: TID

   dob: Date
   dobTime: Date

   dod: Date
   dodTime: Date

   years: number
   months: number
   weeks: number
   days: number
   hours: number
   minutes: number
}

export class Age {

   id: TID = nanoid()

   dob: Date = new Date()

   dobTime: Date = new Date()

   dod: Date = new Date()

   dodTime: Date = new Date()

   years = 0

   months = 0

   weeks = 0

   days = 0

   hours = 0

   minutes = 0
}


import { produce } from "structurajs"

@Injectable({ providedIn: 'root' })
export class AgeStore extends ImmutableStore<TAge> {
  constructor() {
    super( {
             cloneAndMutateFunc: produce, // COMPILE ERROR
             enableLogging: true,
             initialState: new Age(),
             name: 'RegistrationStore',
             plugins: [
               useDevtools(),
               useStoreHistory(),
               useStorePersistence(),
             ],
           } )
  }
}


Compile error:

<T, Q, IS_ASYNC = false>(state: DraftableState<T>, producer: Producer<T, Q, IS_ASYNC>, patchCallback?: PatchCallback<T> | undefined, { proxify }?: ProduceOptions | undefined) => ProduceReturn<...>
is not assignable to type
( currentState: TAge, mutation: ( draftState: TAge ) => void ) => TAge
Types of parameters  producer  and  mutation  are incompatible.
Types of parameters  draftState  and  draft  are incompatible.
Type  UnFreezedObject<TAge>  is not assignable to type  TAge 
The types of  dob.toString  are incompatible between these types.
Type  UnFreezedObject<() => string>  is not assignable to type  () => string 
Type  UnFreezedObject<() => string>  provides no match for the signature  (): string 
immutable-store-config.d.ts(16, 5): The expected type comes from property  cloneAndMutateFunc  which is declared here on type  ImmutableStoreConfig<TAge> 

If I use immer, the error disappears. However, I would like to use structurajs instead. Appreciate your help in correcting the error.

structrajs DOES NOT KNOW HOW TO PARSE Date type

Cheers

Option to applyPatches mutatively (without cloning object)

Hey, thanks for making this awesome library!

I've been looking for a more performance minded alternative to immer, as I'm developing a latency sensitive browser game and want to send game-state patches over the wire, so structura seems like a perfect fit :)

Now my question/problem is whether it's possible to apply patches in a way that manipulates an existing object and skips the cloning step. Reason for needing this is that my object on the client side isn't just an object but only provides an object-like interface with custom setters that wire the data to some other place and I want to avoid re-creating this complex interface every time I receive patches.

// something like
const res = applyPatchesMutatively(myObject, patches);
expect(res === myObject);

Cheers 🙌

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.