Code Monkey home page Code Monkey logo

fable.solid's People

Contributors

alfonsogarciacaro avatar kunjee17 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fable.solid's Issues

F# unions are not deep-cloned in `Solid.createElmishStore`

If the model/state type used with Solid.createElmishStore contains an F# union, the union value is not deep-cloned. This causes any compile-time immutable values inside the union to be unexpectedly mutated at runtime, and also breaks Solid's granular change detection (since Fable emits unions as classes and Solid stores treat classes atomically).

Currently Util.deepClone only handles values whose runtime type is either an array, an F# record, or a plain JS object. Would it be reasonable to add F# unions to this list?

It does look like union types get a single generated prototype method called cases. In order to not break any emitted code that depends on this, one thought I had would be to, as part of the cloning process, copy all the methods from the object's prototype (as well as maybe Union.prototype and System.Object.prototype) onto the instance. Might make sense to do the same for records, too, so that things like ToString continue to work as expected.

useParams somehow not working with Solid-router

I am trying solid-router for routing in solid application. Equivalent Typescript code works without any issue. But F# / Fable code is not working. Generated code looks all ok to me.

Here is fable code.

type SolidRouter =
    [<ImportMember("@solidjs/router"); JSX.Component>]
    static member Router(children: JSX.Element list) : JSX.Element = jsNative
    
    [<ImportMember("@solidjs/router"); JSX.Component>]
    static member Routes(children: JSX.Element list, ?fallback: JSX.Element) : JSX.Element = jsNative
    
    
    [<ImportMember("@solidjs/router"); JSX.Component>]
    static member Route(path : string , ``component`` : JSX.Element) : JSX.Element = jsNative
    
    
        
    [<ImportMember("@solidjs/router")>]
    static member useParams () : 'T = jsNative
    
    [<ImportMember("@solidjs/router")>]
    static member useIsRouting () : unit -> bool = jsNative

all other than useParams works without any issue.

SolidRouter.Router [
        Html.fragment [
            Html.p "Header"
            SolidRouter.Routes [
                SolidRouter.Route("/", View1())
                SolidRouter.Route("/someitem/:id?", View2())
            ]
        ]
    ]
[<JSX.Component>]
    let View2 () =
        let isRouting = SolidRouter.useIsRouting()
        printfn $"{JSON.stringify( SolidRouter.useParams())}"
        let par : {| id : string  |} = SolidRouter.useParams() 
        let id = par.id
        Html.div [
            Html.text $"Is routing {isRouting()}"
            Html.text $"Specific item with {id}"
        ]

and here is generated code.

import { createHotContext as __vite__createHotContext } from "/@vite/client";import.meta.hot = __vite__createHotContext("/dist/pages/SpecificModel.jsx");import { template as _$template } from "/node_modules/.vite/deps/solid-js_web.js?v=2764a46a";
import { insert as _$insert } from "/node_modules/.vite/deps/solid-js_web.js?v=2764a46a";
import { esm as _esm } from "/@solid-refresh";

const _tmpl$ = /*#__PURE__*/_$template(`<div></div>`, 2);

import { useParams, useIsRouting } from "/node_modules/@solidjs/router/dist/index.jsx";
import { toConsole } from "/dist/fable_modules/fable-library.4.0.0-theta-007/String.js";
export const $$registrations = {};

const _Hot$$View1 = function View1() {
  const isRouting = useIsRouting();
  toConsole(`${JSON.stringify(useParams())}`);
  const par = useParams();
  const id = par.id;
  return (() => {
    const _el$ = _tmpl$.cloneNode(true);

    _$insert(_el$, () => `Is routing ${isRouting()}`, null);

    _$insert(_el$, `Specific item with ${id}`, null);

    return _el$;
  })();
};

$$registrations._Hot$$View = {
  component: _Hot$$View,
  id: "_Hot$$View"
};

const {
  handler: _handler,
  Component: _Component
} = _esm($$registrations._Hot$$View, !!import.meta.hot);

if (import.meta.hot) import.meta.hot.accept(_mod => {
  _handler(_mod) && import.meta.hot.invalidate();
});
export const View = _Component; 

Any pointers to debug would be so helpful.

Stack overflow when the model includes large lists (1k-2k elements)

I am writing an entry for Fable.Solid Elmish in krausest/js-framework-benchmark. The benchmark involves creating, rendering, appending, updating, and deleting rows.

The implementation fails with the error below when the number of rows goes beyond 1k.

image
I'm pretty sure application code is not at fault here; the update function returns control without any errors after adding over 1k elements to the model. You can see the full code here: App.fs

Rx Observable binding possible?

I really like this project because it's simply a wrapper of the cutting-edge web JS library and directly depends on the latest release of solid.js v1.5.

I have not used Solid seriously yet, but I recognized the framework is the fastest next to vanilla.js without virtual-DOM and way much simpler than React although taking advantage of JSX.

I also feel very promissing to have found the strong ecosystem with user Add-on
, so if something is really needed from the Fable side, we can take advantage of developing Fable Add-on.

I see several add-on for state management that is so flexible for them to allow unlike React, but I also see their native API has

https://www.solidjs.com/docs/latest/api#observable


observable

import { observable } from "solid-js";

function observable<T>(input: () => T): Observable<T>;

This method takes a signal and produces an Observable. You can consume it from another Observable library of your choice, typically with the from operator.

// How to integrate rxjs with a solid.js signal
import { observable } from "solid-js";
import { from } from "rxjs";

const [s, set] = createSignal(0);

const obsv$ = from(observable(s));

obsv$.subscribe((v) => console.log(v));

You can also use from without rxjs; see below.

from

New in v1.1.0

import { from } from "solid-js";

function from<T>(
  producer:
    | ((setter: (v: T) => T) => () => void)
    | {
        subscribe: (
          fn: (v: T) => void
        ) => (() => void) | { unsubscribe: () => void };
      }
): () => T;

A helper to make it easier to interop with external producers like RxJS observables or with Svelte Stores. This basically turns any subscribable (object with a subscribe method) into a Signal and manages subscription and disposal.

const signal = from(obsv$);

It can also take a custom producer function where the function is passed a setter function returns a unsubscribe function:

const clock = from((set) => {
  const t = setInterval(() => set(1), 1000);
  return () => clearInterval(t);
});

So, currently, I wonder how it's possible to combine Fable.Solid and Observable of Rx for F# that is
https://github.com/fsprojects/FSharp.Control.Reactive

In short, it would be very nice to have Observable of Rx version for the typical counter-demo.

[<JSX.Component>]
let Counter() =
    let count, setCount = Solid.createSignal(0)
    let doubled() = count() * 2
    let quadrupled() = doubled() * 2

    Html.fragment [
        Html.p $"{count()} * 2 = {doubled()}"
        Html.p $"{doubled()} * 2 = {quadrupled()}"
        Html.br []
        Html.button [
            Attr.className "button"
            Ev.onClick(fun _ -> count() + 1 |> setCount)
            Html.children [
                Html.text $"Click me!"
            ]
        ]
    ]

Thanks!

Nice

Thanks for your great work! @alfonsogarciacaro

Actually, I was thinking of suggesting migrating to esbuild/vite for Fable projects because the slow old-fashioned Webpack prevailed.
This is so nice.
I also wish the new Fable4 template will be provided with vite. Thanks.

lazy method should be added

Solidjs supports something called lazy function for lazy loading. Can we have that here or is it even possible ?

import { lazy } from "solid-js"; // <- THIS ONE
import { Routes, Route } from "@solidjs/router"
const Users = lazy(() => import("./pages/Users")); // <- Is it possible to have import like this in fable. It is file import afaik
const Home = lazy(() => import("./pages/Home"));

export default function App() {
  return <>
    <h1>My Site with Lots of Pages</h1>
    <Routes>
      <Route path="/users" component={Users} />
      <Route path="/" component={Home} />
      <Route path="/about" element={<div>This site was made with Solid</div>} />
    </Routes>
  </>
}

Add created resource to solid js library

createresource. We should add createresource api to solidjs as well.

I don't know how I am going to transit between async and promise for createresource api. Below definition for createresource

export declare function createResource<T, R = unknown>(fetcher: ResourceFetcher<true, T, R>, options: InitializedResourceOptions<NoInfer<T>, true>): InitializedResourceReturn<T, R>;
export declare function createResource<T, R = unknown>(fetcher: ResourceFetcher<true, T, R>, options?: ResourceOptions<NoInfer<T>, true>): ResourceReturn<T, R>;
export declare function createResource<T, S, R = unknown>(source: ResourceSource<S>, fetcher: ResourceFetcher<S, T, R>, options: InitializedResourceOptions<NoInfer<T>, S>): InitializedResourceReturn<T, R>;
export declare function createResource<T, S, R = unknown>(source: ResourceSource<S>, fetcher: ResourceFetcher<S, T, R>, options?: ResourceOptions<NoInfer<T>, S>): ResourceReturn<T, R>;

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.