I finally got some time and motivation to start the port to Fable.Core 3.
I know you had a long pre-release phase for exactly this kind of feedback, sorry for ignoring that and only complaining after the release.
Most of the upgrade was just a little bit of churn, changing a namespace here or replacing Error with Exception there. So I expected it to be worse.
I have two use cases that have been broken:
Some of these are just replacements that need to be done in ts2fable (like Error -> Exception), this is already tracked by https://github.com/fable-compiler/ts2fable/issues/298. Most of these I've just done by hand.
Other things have been removed which don't have any (obvious) replacement in F#:
These two are native JS types (ref https://github.com/fable-compiler/Fable/issues/1805)
These are TS types, which would be nice to have for ts2fable
Array<'T>: you would expect to be able to just replace Array<'T> with 'T array, but in babylonjs a few classes inherit from Array<'T>, so it needs to be an interface ¯\_(ツ)_/¯ReadOnlyArray<'T>ArrayLike<'T>PromiseLike<'T>There are also a few missing browser bindings (examples: AudioContext, WebGLObject, FrameRequestCallback, ...) but I think for this I should open an issue (or even better PR) in the new browser repo.
Most of these are not really useful when actually writing code (you wouldn't use Function in F#, instead you'd probably use a generic), but are required for TS/JS bindings.
I know you have been moving away from ts2fable to handwritten bindings, but that is just not feasible for me. babylon.d.ts has 49694 lines, the generated F# binding has 28881 lines. No way can I bind that by hand.
(ref https://github.com/fable-compiler/Fable/issues/1812#issuecomment-486580499)
I am using web workers and Transferable objects. This means I __must__ use ArrayBuffer:
The ArrayBuffer, MessagePort, ImageBitmap and OffscreenCanvas types implement this interface.
So I can't use byte array, because the JS type UInt8Array is not Transferable, only the underlying ArrayBuffer is.
In another case I receive data from a GET, and then use the ArrayBuffer and the different views over it to performantly extract the data from it.
I tend to develop in two different styles with Fable:
_F# native_, when doing business logic or elmish views, _JS-like_ when porting JS code, or for performance sensitive code (raw ArrayBuffers etc).
So I would prefer to still have Error, RegExp, etc available, so I know exactly what is and isn't available in JS, but I can understand your want to reduce duplication and it does make sense to remove them.
I think I can re-add most of these types to my own project and unblock me in the short term.
Of course I'd be most happy if these were added back to Core, because in the old times everything was better. 👴
(https://github.com/fable-compiler/Fable/issues/1812#issuecomment-486580499)
But if you need to specific JS features the old JS typed array bindings could be published in another package (we would need a volunteer for that) or you can just copy them into your project [...]
If you can give me a little guidance I'd like to do just that if you _really_ don't want them in core.
I don't think (I hope ...) anything of this actually depends on Fable Compiler internals, so it should be possible to implement outside of core.
I want to use these from ts2fable, so it would be great if this package was in the fable-compiler group, I don't want to tell people they need to install the package 0x53A.Fable.TypescriptInterop.
How would you split it? One package for JS types (typed arrays + Function/Symbol) and one for the TS interfaces (ArrayLike, ...), or everything into one? It isn't much (yet), so I think I'd put everything into one.
Naming?
It also looks like the JsContructor with parameters (1 and 2) was removed. Was that on purpose?
Here they were added: https://github.com/fable-compiler/Fable/commit/42017c0794592538867052d965367a189ecff9c8
But they don't exist in the current source: https://github.com/fable-compiler/Fable/blob/c12678d4cbff2fd7e7bc29dca5ae83ab868bffab/src/Fable.Core/Fable.Core.JsInterop.fs
It looks like they were removed with 2.1.0: https://github.com/fable-compiler/Fable/commit/bda083367c967f84d57ac286dd198a573fa134c9
On the missing features in Fable.Core I also have https://github.com/fable-compiler/Fable/issues/1831 where Promises signatures aren't tracking JS ones anymore.
For Function I use System.Delegate but it sadly mean a loss of information as JS functions have a bunch of things available that delegates can't do.
Sorry for taking so long to reply. I was waiting for things to calm down after the Fable.Core 3 release :) Here are some of my comments:
I apologize for the inconvenience of removing APIs from Fable.Core but I'm trying to be very conservative now in adding things back (or new things). This is because all Fable projects depend on Fable.Core which makes it difficult to make changes. I'd prefer to keep only the minimum stuff to run Fable apps.
About ts2fable, unfortunately it's been a while since I lost touch with its code base. Seems the project is kind of dormant now. We'd likely need new maintainers to revive it :/
About native arrays, yes, besides simplifying things I wanted to unify code in samples, tutorials, etc. But I understand some JS-only APIs like buffer are need some times. I'm trying to resolve this using extensions (some haven't been published yet), we can add a few more or you can also easily add them to your project: https://github.com/fable-compiler/Fable/blob/1b9aa557ad8c1f226f6412dbe0b182775541c97f/src/Fable.Core/Fable.Core.Extensions.fs#L11-L20
Nothing depends on Fable internals for the JS bindings, so you basically can take anything you need from the old Fable.Import.JS and put it in a package or in you project.
About JsConstructor, this was also to reduce the number of ways of importing things from JS. When importing single functions, ImportAttribute or import expressions are preferred. It's true this is a bit more difficult when importing a constructor, but you can combine Import and Emit attributes for that:
open Fable.Core
open Fable.Core.JsInterop
type IMyType =
interface end
[<ImportMember("./my-lib"); EmitConstructor>]
let MyConstructor(x: int): IMyType = jsNative
let x = MyConstructor(5)
// import { MyConstructor } from "./my-lib";
// export const x = new MyConstructor(5);
I'm trying to be very conservative now in adding things back (or new things)
Understandable, then we have (hopefully) less issues when migrating 3.x -> 4.x
About ts2fable, unfortunately it's been a while since I lost touch with its code base. Seems the project is kind of dormant now. We'd likely need new maintainers to revive it :/
I wouldn't doom it too fast, @humhei is still active on it. In the past I sent a few PRs to fix my own issues (https://github.com/fable-compiler/ts2fable/pulls?q=is%3Apr+is%3Aclosed+author%3A0x53A), and there were also other contributors.
I feel it's more a case of that it works (mostly) for the people that use it.
Babylon.js 4 uses a lot of advanced typescript features, like mapped types, so when I migrate from 3.x to 4.x I'll be forced to extend ts2fable anyway (or create my own tool, or whatever), because no way can I do the binding by hand.
[...] extensions [...]
Nothing depends on Fable internals for the JS bindings, so you basically can take anything you need from the old Fable.Import.JS and put it in a package or in you project.
for my own use cases I created https://github.com/0x53A/fable-tsinterop-ex
Will take a look if I can move to your extensions package and delete my own,
About JsConstructor [...]
I think I can move to the attributes, didn't know about them. Thanks!
Closing, please reopen if there are further questions
Most helpful comment
@0x53A Some of those missing types were added back to
ts2fablein this PR, the full list is here.