Port shared core from LG to pure OCaml + new lui - #8
Conversation
Hand-written .ml/.mli for the dependency-free and low-dependency core modules: string_kit, journal, sync_state, sync_checkpoint, sync_protocol, edn, asset_files, datascript_value, sqlite, storage_codec, ref_text, snapshot_codec, e2ee, host_update, outliner, graph_bootstrap_data. shared/native/dune now compiles src/*.ml via copy_files; opam pins updated (lui -> c4468ff, +ocaml-signal, +ctypes, -lg/lg-test/signal-lg/ datascript-ocaml-lg). Entry exe stubs keep artifact names.
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
Pure OCaml rewrite of the model reducer and view_base helpers against the new lui/ocaml-signal API; LG dialect files removed as sources are ported.
- logseq_chat_app library: Model/App/View*/Native_bridge/Response_snapshot ported to pure OCaml on new lui + ocaml-signal (ctypes crypto FFI) - extension schemas (outliner-editor/block-content, nav-stack, search-presentation, overflow-menu, liquid-glass tweak) declared via Lui_extension; element callsites follow new node-kind/property validation (~text on leaf kinds, InlineIconName, tweak wraps child) - shared/test rewritten as alcotest test_main exe with ported edn/sync_state/sync_checkpoint/live_sync/asset_files/snapshot/ lui_projection suites exercising the real native bridge - requires lui runtime fix: deactivate dynamic segments on dropped subtree nodes (nested conditional unmount ordering) - upstream PR to logseq/lui pending
…ashcards, outliner, lui_host_update, lui_snapshot) - expose Markup.append_node/youtube_timestamp/tweet_id/fenced_code and Fractional_order.suffix needed by the ported tests - 67 cases green
…ound by tests - Port graph_read, mobile_graph, outliner_state, pending_projection, pending_ops, model, sqlite, sync_session, outliner_effects, e2e_seed_data, logseq_storage_codec, platform_crypto tests to alcotest - Fix breadcrumbs order (root-first) and make sidebar recent pages lazy so decrypt only runs for the visible window - Expose pending_ops store_raw/list_raw/raw_title/json helpers in mli
- port app_test.cljc to app_test.ml; all 174 deftests now run under the alcotest harness (707 tests total) - fix view ports found by the tests: liquid-glass tweak only on iOS/SwiftUI, mount-time context for native search/navigation props, on_change for the language radio, autofocus signal on the composer textarea, selected state on the outliner row box, 42pt hide-keyboard button width - delete the 111 .cljc sources now fully ported to OCaml - rename lg-coverage helpers to coverage_check and retarget the feature-coverage script at graph_runtime.ml - drop .lg-cache from gitignore/CI and update README/AGENTS lg mentions
logseq/lui#21d5c9e deactivates a node's dynamic segments on drop so stale prop publishes fail fast instead of mutating a dead subtree; the app test suite exercises it through native-navigation-stack.
- ctypes.foreign in shared/native requires the ffi library at app link time (LogseqChatShell failed with undefined _ffi_* symbols); the iOS SDK ships libffi.tbd for both device and simulator. - pre-existing on main (3e0c785): drop the duplicated LGChatPlatformCommandHandling protocol and LGChatSettingsPayload struct declarations, and restore @mainactor on LGChatRuntime and the protocol so actor isolation type-checks again. Verified end-to-end in the iPhone 17 simulator (iOS 27.0): the ported OCaml core renders the sign-in screen, drives the Cognito hosted UI, and reaches the post-auth graph picker.
|
iOS simulator E2E verification of the OCaml port — passed end-to-end including real Cognito sign-in. Built
"Couldn't load graphs / Connection refused" is expected — the sync API at Blockers found and fixed (committed on this branch)
Related: logseq/lui#3 upstreams the |
ocaml-signal builds its library in melange mode, so dune build -p needs melc; without the declared dep, opam on a clean switch (CI) can build it before melange installs and fail with 'Program melc not found in the tree or in PATH'. Pinned to the logseq/ocaml-signal#2 commit that declares melange.
The previous lockfile still vendored lg, lg-test, signal-lg and datascript-ocaml-lg. Regenerated with: opam monorepo lock --ocaml-version=5.5.0 --opam-provided=ocaml-compiler logseq_chat Private pins without dev-repo metadata (lui, datascript_ocaml, mldoc, persistent_sorted_set_ocaml) are not vendored by the lockfile; CI clones them from pin-depends as before.
Summary
Ports the shared core from LG-generated OCaml (
%{bin:lg}+.cljcsources) to hand-written OCaml against the new pure-OCamlluiandocaml-signal, mirroring logseq/lui#2. Thelg,lg-test,signal-lg, anddatascript-ocaml-lgdependencies and all lg build plumbing are removed; FFI goes throughctypes, views uselui_ppxreactive, and every ported.mlhas a.mli.Status: complete —
dune build @shared/native/runtestis green with 707 tests across 36 alcotest suites, including all 174 cases ported fromapp_test.cljc. Verified end-to-end on the iOS simulator (sign-in → Cognito hosted UI → graph picker; see comment below).What changed:
core/modules and the app layer (model,view*,app,snapshot,native_bridge,native_crypto,entry/) ported to.ml+.mli; the 111.cljcfiles are deleted.datascript-ocaml-lgcall sites now useDatascriptdirectly.shared/native/dune/shared/test/dunerewritten for plain OCaml; artifact names preserved (logseq_chat_mobile_entry.exe.o,logseq_chat_e2e_seed.exe,logseq_chat_live_sync.exe) soscripts/build-mobile-*.shstill link.logseq_chat.opam: dropped the lg stack; addedocaml-signal,ctypes,alcotest;luipinned to21d5c9e— thedrop_nodedynamic-segment fix upstreamed as Deactivate dynamic segments when their parent node is dropped lui#3 (pin points at the pushed commit so CI gets it; repin to main after that merges)..linkedLibrary("ffi")for ctypes; removed duplicated Swift declarations and restored@MainActoronLGChatRuntime(pre-existing breakage on main).lg-coverage.ml→coverage_check.ml,test-lg-coverage.sh→test-coverage-check.sh) and retargeted atgraph_runtime.ml;.lg-cacheremoved from gitignore/CI; README/AGENTS updated.Translation conventions:
Rrbvec.t→list,(type-record …)→ records,(type-variant …)→ variants,atom/deref/swap!→ref,loop/recur→let rec,let*→Result.bind, transit EDN decode →Melange_edn_native/Transit_core.Json,(ffi …)→Ctypes.foreign.Link to Devin session: https://app.devin.ai/sessions/a3287ca9a4364c47ab22a258364ddc1f
Open in Devin Desktop: https://app.devin.ai/desktop/session/a3287ca9a4364c47ab22a258364ddc1f?variant=devin
Requested by: @tiensonqin