Skip to content

Releases: Fausto95/lucent

@lucent-lang/lucent@0.2.0

Choose a tag to compare

@github-actions github-actions released this 06 Oct 12:30
156c0af

Minor Changes

  • #99 a36e7d8 Thanks @Fausto95! - lucent doctor reads the app's build: the steps the last build failed at (an Android dependency conflict, with its log), why steps ran again, a platform this JavaScript was built without, and whether the newest Xcode or Gradle build of the app was built from these sources, judged as the app judges it

  • #102 296d799 Thanks @Fausto95! - Offer quick fixes in the editor where a diagnostic's fix is exact (a thrown string becomes an Error, a copied prop is read in place, a missing module import is added), and name what each SDK class and member calls natively in its doc comment, so hover and lucent sdk show say where it comes from

  • #103 733d318 Thanks @Fausto95! - Every command's --json now writes one JSON document described by a published schema (explain, new module and clean gained one), or is refused with exit code 2 by commands without JSON output (init, dev, trace), and errors under --json go to stderr instead of being dropped

  • #88 cb08732 Thanks @Fausto95! - Show a native view's children by condition ({cond && <X />}, {c ? <X /> : <Y />}) and as keyed lists ({items.map((item) => <X key={item.id} />)}), keeping each kept item's view, and accept a quoted value for an Android setter prop (text="note")

  • #97 c737a47 Thanks @Fausto95! - Lay out native view JSX with React Native's Yoga: <Flex style={{ flexDirection: "row", gap: 8 }}> from lucent:ui places its children, each child's layout={{ flexGrow: 1 }} places it, and native containers (stack views, LinearLayouts) keep laying out their own

  • #98 c896eb6 Thanks @Fausto95! - Report coverage of every SDK module with lucent sdk coverage --all (modules the extractor cannot read are listed, not fatal), and append a markdown summary of why members are left out with --summary <file>

Patch Changes

  • #87 2bffa45 Thanks @Fausto95! - Declare the initializers an iOS class inherits through a superclass that inherits them too (init(coder:) on UIWindowScene.ActivationAction) on every build, not only when the SDK's classes happen to be read in order

  • #85 36064d4 Thanks @brunokiafuka! - Keep every Swift overload of one name that a Swift overlay gives an Objective-C class: NSCoder.decodeTopLevelObject(forKey:) and RunLoop.schedule(after:tolerance:options:_:) were dropped beside their first overload. A Swift inout parameter is now skipped with its reason, instead of binding the member as if it took a value and generating a shim that does not compile.

  • #92 9ced06c Thanks @brunokiafuka! - Call an arrow function passed straight to sort, map, filter, forEach, reduce and the like directly, instead of through a function value: sortNumbers runs 1.4x faster, and generated code is smaller.

  • #100 62b6f69 Thanks @Fausto95! - Read uint32 values back out of a number[] without mispredicting (crc32 runs 1.8x faster), and index arrays with a number without a C library call on x86-64 hosts without SSE4.1, which made sieve far slower on Linux CI.

  • #93 93ecab0 Thanks @brunokiafuka! - Keep arithmetic whose range is proven, such as sum = (sum + x) % m, in integer registers: xorshift runs 3x faster. Arithmetic that could give -0, NaN or a value past 2^53 stays a double.

  • #90 eb6975b Thanks @brunokiafuka! - Make strings cheaper: each is one allocation, or none up to 15 Latin-1 characters, and short strings compare and hash faster as Map keys; join allocates once. The strings and wordCount benchmark kernels run 1.5–1.8x faster.

@lucent-lang/lucent@0.1.3

Choose a tag to compare

@github-actions github-actions released this 04 Oct 23:55
6dcccc3

Patch Changes

  • #80 86500a7 Thanks @brunokiafuka! - Add errorOf(throwable) to lucent:android: the Error Lucent makes of a thrown Java exception (its code the class name, java.lang.IllegalStateException), for adapters whose callback API reports failure with a Throwable. reject(errorOf(e)) now rejects as the call would have thrown.

  • #64 fe9758d Thanks @Fausto95! - Start every lucent command about 0.1 s sooner: Node keeps the compiled code of the CLI and TypeScript on disk between runs.

  • #68 fbb8e10 Thanks @Fausto95! - Bind the version of a native library installed now in lucent dev and the editor: after a pod install or a rebuilt Swift module, the next rebuild uses its new API instead of the one the process first read.

  • #65 23cc5a1 Thanks @Fausto95! - Let lucent build --platforms ios (or host) succeed before the app's Android dependencies are resolved: imports of them in Android code are left untyped with a warning pointing to the Android build, instead of failing with LUCENT3004.

  • #78 88cef84 Thanks @Fausto95! - Bind Kotlin function types on Android: a (Double) -> Unit parameter, property or result is a TypeScript function instead of the Function1 class, so a Lucent function can be passed or assigned to it and a Kotlin function Lucent gets can be called. A property of a fun interface's type (any Java interface with one abstract method) now takes a function too, in module code, in a view's setup and as a JSX attribute.

  • #79 04409e3 Thanks @Fausto95! - Call more Kotlin shapes on Android: generic members whose type parameters have bounds (fun <T : Comparable<T>> top(items: List<T>)), with their defaults left out; assigning a value class property; and Lucent classes implementing a Kotlin interface's suspend members (the async method's promise resumes Kotlin) and members taking or giving value classes. Declarations of a class with a value class property are valid again: its accessors are named getBest, not getBest-JdFk__0.

  • #68 fbb8e10 Thanks @Fausto95! - Say what to do when a native library's type has no member the code uses: the error names the module and the installed version (pod:Name@version) that declare the type, after a library update removed or renamed it. On iOS, for a type only named in another module's signatures, it says to import its module.

  • #75 23704bd Thanks @Fausto95! - Add --views to lucent sdk coverage: with the internal views switch on (LUCENT_VIEWS=fabric), it lists each view class of a module as a JSX tag, how a tag makes it, the props and events its declarations give, whether it takes children, and what is left out and why.

  • #64 fe9758d Thanks @Fausto95! - Make each lucent build and lucent check start faster: the declarations of the SDK frameworks a project imports are kept in the SDK cache instead of written again by every run (a check importing UIKit: 1.9 s to 1 s).

  • #64 fe9758d Thanks @Fausto95! - Make rebuilds in lucent dev, checks in the editor and repeated builds faster: the declarations of the SDK frameworks a module imports are written once per process instead of for every compile.

  • #81 d163b8f Thanks @Fausto95! - Call each Swift initializer that differs from another only by its argument labels: init(service: String) and init(accessGroup: String) become Keychain.withService(…) and Keychain.withAccessGroup(…) instead of two constructor(string) overloads, where new Keychain("x") silently called the first one declared; new with such arguments is now an error naming the factories. An unlabeled initializer among them stays the constructor, as Swift calls it. CryptoKit's P256 keys and signatures are made with withRawRepresentation(…), withX963Representation(…) and the like.

  • #82 dd2a572 Thanks @Fausto95! - Bind the Swift packages an app adds to its Xcode project: Lucent reads the project and Package.resolved, builds each package's library products at its pinned version for the simulator, binds their modules by rule, and links the ones the code imports into LucentNative (add the package to the project without adding its product to the app target, which would link it twice). iOS declarations are now read for the app's deployment target (IPHONEOS_DEPLOYMENT_TARGET), so an API the app's target already has no longer needs an available("ios", …) check, and one newer than it does.

  • #83 10cfcfc Thanks @Fausto95! - Bind more of what Swift declares on iOS: tuples (as TypeScript tuples, labels as element names), closures passed to or returned by Swift (as Lucent functions, through Objective-C blocks), Objective-C factory initializers Swift imports as init (+widgetWithLabel: as new Widget(label)), and C functions Swift imports as members of CoreFoundation-style handles (cgImage.width, cgImage.cropping(rect)). new of a class whose initializers come from a module no file imports now says to import that module.

  • #68 fbb8e10 Thanks @Fausto95! - Explain a native member Lucent does not bind: calling one the extractor skipped (a Swift tuple, say) now says it exists in the library, why it is not bound, and to wrap it in Swift or Kotlin of your own, rather than that the installed version lacks it. A member refused for a type that cannot cross yet (LUCENT2002) gets the same fix.

@lucent-lang/lucent@0.1.2

Choose a tag to compare

@github-actions github-actions released this 03 Oct 16:24
fe31951

Patch Changes

  • #63 e160e7a Thanks @Fausto95! - Build again where one platform's SDK is missing (Android on a machine without Xcode) when a module picks a value with PLATFORM === "ios" ? … : …: the host build no longer reports LUCENT2001 for the side it cannot type.

  • #60 820fe5f Thanks @Fausto95! - Make for … of over arrays of objects, strings or arrays faster: each element is moved into the loop's variable instead of copied.

  • #63 e160e7a Thanks @Fausto95! - Make builds, checks and the editor faster when modules import iOS frameworks: the names of the frameworks they reference are read from the SDK cache once per build instead of once per lookup.

  • #60 820fe5f Thanks @Fausto95! - Say to run pod install first when an iOS module isn't found and the app's pods haven't been installed yet, instead of naming only the SDK's frameworks.

  • #63 e160e7a Thanks @Fausto95! - Ask Xcode where the iOS SDK is once per process, instead of again for each build whose options differ.

@lucent-lang/lucent@0.1.1

Choose a tag to compare

@github-actions github-actions released this 02 Oct 00:24
e31a99f

Patch Changes

  • #56 cbe8cd1 Thanks @Fausto95! - Compile a program that calls compute and disposes an Android AutoCloseable with [Symbol.dispose](), which crashed the compiler.

  • #56 cbe8cd1 Thanks @Fausto95! - Compile functions, methods and modules through Lucent's semantic IR, which checks evaluation order, types and control flow before it generates native code.

@lucent-lang/lucent@0.1.0

Choose a tag to compare

@github-actions github-actions released this 30 Sep 17:51
7161111

Minor Changes

  • #13 9031f4e Thanks @Fausto95! - Give Android code the app's Activities. lucent:android adds currentActivity() (the Activity in front, or null; Lucent holds Activities weakly), startActivityForResult(intent, signal?) and requestPermissions(permissions, signal?) (promises settled once with the answer; aborting forgets the request, and a late answer is dropped), and onActivityEvent(event, handler) for the Activities' lifecycle and new intents. Requests go through a translucent Activity of Lucent's, so they work with any app Activity and survive it being recreated meanwhile. The native package's manifest declares it and a provider that starts tracking Activities with the process. Package manifest components may now set an activity's theme and configChanges.

  • #13 9031f4e Thanks @Fausto95! - Support bigint: literals, every operator JavaScript has for it, BigInt(), BigInt.asIntN and asUintN, Number() and String() of a bigint, and bigints in collections, objects, classes, unions and async code. Values of any size cross the JavaScript boundary exactly, and loose == between a bigint and a number or string, which converts in JavaScript, is reported as LUCENT1002.

  • #13 9031f4e Thanks @Fausto95! - Turn callback APIs, such as a native listener, into promises and subscriptions with fromCallback and subscribe from lucent:core: each settles once, whichever callback or abort comes first, and runs the cleanup you return exactly once.

  • #13 9031f4e Thanks @Fausto95! - Say exactly what the app needs after a build. lucent build lists actions (also in --json and the build record): recompile native code, reload JavaScript, repackage resources, relink native dependencies or reinstall the app, each with its platforms and the files behind it. They come from what the build changed: a body edit recompiles, new exports also reload JavaScript, a package's resources are repackaged. lucent dev now watches Lucent packages outside the app (workspace or linked) whole, including their lucent.json and native files, never rebuilds for what builds write, and stops a build a newer change made stale before it writes anything. Generated files are replaced whole, so Metro never reads half a proxy. Package files are hashed once while their size and times hold, and lucent build no longer starts a second Gradle run while another one resolves the classpath.

  • #13 9031f4e Thanks @Fausto95! - Run heavy work on worker threads with compute(task, input, { signal }) from lucent:core. The task is a function declared at the top level of a module, taking one parameter, and runs on a bounded pool of workers without a second JavaScript runtime; the promise settles on the calling thread. The compiler checks everything the task runs (no module state, no main-thread or unknown native code, no function values it cannot follow, nothing asynchronous: LUCENT3011) and that its input and result are data (LUCENT3012), naming the path to what breaks the rule. The input is copied when compute is called, keeping aliases and cycles; aborting the signal rejects the promise at once, and a running task stops at the next iteration of a loop in the task or in a module function it calls (loops in closures, methods and generic functions, and native calls, run to their end first). The JavaScript version in @lucent-lang/lucent/core behaves the same on the calling thread, for tests.

  • #13 9031f4e Thanks @Fausto95! - Recognize components: an exported function of a .lucent.tsx module that returns a platform view (a UIKit UIView, an Android View, or a subclass). React can't render them yet. Lucent now checks them and leaves them out of the module's JavaScript. It checks that the view comes back on every path, from one props object of plain data, with callback props named on… that return nothing, and that setup code can run on the main thread. The new diagnostics are LUCENT3020 to LUCENT3023. compile() lists each component under components, identified by package, module path and export name.

  • #13 9031f4e Thanks @Fausto95! - Check iOS availability as Android's is checked: an Objective-C or Swift API newer than iOS 15.1 must be used under available("ios", major, minor?) (in an if, after an early exit, or in ?: / &&), or the build fails with LUCENT3007 instead of crashing on older devices. Swift shims are marked @available from what they call, so they compile against the deployment target.

  • #13 9031f4e Thanks @Fausto95! - Lucent classes can extend Objective-C classes on iOS, as they extend SDK classes on Android: class Greeting extends UIViewController is made with the base initializer super(…) names, its methods override the base's (UIKit calling viewDidLoad runs the Lucent one), super.viewDidLoad() calls UIKit's, and inherited members such as this.view work on the instance, which passes wherever the base type is taken. A generated Objective-C subclass stands for each instance; it and the Lucent object keep each other alive while either side uses them, without a cycle. Subclasses of main-thread classes are used on the main thread.

  • #13 9031f4e Thanks @Fausto95! - Native 64-bit integers are bigints: Java's long (long[] as bigint[]), int64_t, uint64_t, NSInteger, NSUInteger and Swift's Int, Int64 and UInt64, in arguments, results, properties, struct fields, Outs, callbacks and constants. Every native value is exact, NSNotFound and Long.MAX_VALUE included, and a bigint the native type cannot hold throws RangeError naming the parameter or field. Enums, option sets and @IntDef/@LongDef groups stay numbers. Code that passes numbers to these APIs must pass bigints now (1000n, BigInt(n)), and Number(list.count) turns a count or index back into a number.

  • #13 9031f4e Thanks @Fausto95! - Hand bytes between Lucent, compute tasks and JavaScript without copying them, with NativeBuffer from lucent:core. NativeBuffer.allocate(size) and NativeBuffer.from(bytes) make one; withRead(read) and withWrite(write) lend a callback the bytes for one call as a span with a Uint8Array's element semantics (reads share the buffer, a write needs it to itself, a conflicting borrow throws an InvalidStateError); transfer(), or passing the buffer to compute, moves the bytes to a new owner and leaves every reference to the old buffer refusing them; toUint8Array() and from are the only copies, and NativeBuffer.stats() counts them. The compiler keeps a span inside its callback (LUCENT3030: not returned, stored, captured by a closure that outlives the call, kept by a callee or held across await) and reports a buffer used after it certainly moved (LUCENT3031). JavaScript receives a buffer as an opaque handle with the same methods, whose borrows lend it a copy, so it never holds memory a worker may be writing. Uint8Array keeps its copy semantics.

  • #13 9031f4e Thanks @Fausto95! - Add typed native extensions. A Lucent package declares one in lucent.json (extensions.<name>): a C header in native sources both platforms build, the opaque structs Lucent code holds as handles (their create, destroy, methods and thread), what pointer parameters are (bytes with their length, a UTF-8 string, an error struct) and how results report failure. lucent build reads the header with clang, checks every name and shape against it, and fails naming the package and the field when they disagree. Lucent code, shared code included, imports the handles as classes and the functions by their C names from lucent:ext/<name>: handles close once (close(), using, or their last reference), throw InvalidStateError after, and cannot cross to JavaScript; a reported failure throws an Error with C's message and code; 64-bit integers are bigints; an exception escaping C ends the process at the call instead of unwinding through Lucent. The header must declare its functions in extern "C" for C++; a function taking a handle is bound only when the declaration names it; a close() from another thread waits for the calls using the handle. Editors get the declarations from `.lucent/native/types/...

Read more

@lucent-lang/lucent@0.0.4

Choose a tag to compare

Patch Changes

  • #8 80aceab Thanks @Fausto95! - Keep instanceof working for Lucent classes after an app reinstalls Lucent without a new JavaScript runtime: new instances now share their class's prototype.

  • #7 edaff0e Thanks @Fausto95! - Build the CLI and compiler with Vite+ (tsdown on Rolldown) instead of esbuild: the published package keeps the same files, and its JavaScript is about 5% smaller.

v0.0.3

Choose a tag to compare

@github-actions github-actions released this 22 Sep 15:17

Full Changelog: v0.0.2...v0.0.3