Skip to content

FM-PS-LYNX-008: architecture stack + verify fixes - #30

Closed
djwok wants to merge 14 commits into
drkz/fm-ps-lynx-008-web-download-febffrom
drkz/fm-ps-lynx-008-native-build-fix-4330
Closed

djwok wants to merge 14 commits into
drkz/fm-ps-lynx-008-web-download-febffrom
drkz/fm-ps-lynx-008-native-build-fix-4330

Conversation

@djwok

@djwok djwok commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

Collapses the remaining FM-PS-LYNX-008 stack into one PR targeting main.

H (verification gate) already landed in #23. This branch was rebased onto current main (verification-gate commit skipped as already applied; no conflict resolutions). Intermediate stacked PRs #24–#29 are superseded by this tip.

Stack (E → A → B+C → F → D+G + verify fixes)

E — one LynxHost for PrimJS globals

src/host.ts: PrimJSLynxHost + fake test host. NativeModules, GlobalEventEmitter, platform, text codec, fetch, and AbortController install go through one seam. Not public API.

A — SyncStreamTransport

Three adapters: NativeHttpFetch (primary; streamingId / GlobalEventEmitter — issue #21 realtime), LynxFetchModule, host-fetch. LynxRemote.ts is a thin pick. FM-PS-LYNX-003 diagnostics removed.

B+C — NativeSyncHttp split + idle-complete fallback

Native /sync/stream HTTP lives in NativeSyncHttp (Android + iOS), not on the SQL RPC module. Idle-complete is the fallback only when streamingId is absent.

F — shared NDJSON fixtures

Canonical catalog at shared/fixtures/sync-stream.json, replayed by JS tests and native fixture tests.

D+G — Android ps_sql JNI + iOS host event sender

Android SQL RPC is JNI PsSqlEngine → shared/ps_sql (androidx.sqlite-bundled removed). iOS no longer walks UIWindow; incremental stream needs setSharedStreamEventSender: (showcase already registers the LynxView).

Web download

Host-fetch keeps a usable Fetch Response.body. PrimJSLynxHost finds bare lynx on lynx-bg, so an emitter is always present on web — do not wait on native onData for identifier fetch. streamingId still uses GlobalEventEmitter. src/globals.ts no longer redeclares Lynx globals (rspeedy TS2403).

Native build fix

iOS: local PSLynxStreamEventSender protocol so sendGlobalEvent:withParams: compiles without importing LynxView. Android NDK: AttachEnv uses JNIEnv** under __ANDROID__, OpenJDK void** for Linux make test.

Confirmed not dropped

Verify

  • pnpm typecheck, pnpm lint, pnpm test
  • make test (Linux; includes JNI -c of ps_sql_jni.cc)
  • make test-ios / Android NDK + instrumentation need Mac

Tracking: #18

Open in Web Open in Cursor 

djwok and others added 14 commits September 9, 2026 21:13
…les) (#23)

chore: verification gate for Node 22.18, CI, and typecheck

Pin the package Node floor at >=22.18, ship Autolink consumer ProGuard
keep rules, and add a CI workflow that runs unit tests, typecheck, lint,
and Linux native `make test`. Clear typecheck by stubbing connectors and
typed NativeModules/Response harnesses instead of invalid casts.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: 達達 <djwok@users.noreply.github.com>
FM-PS-LYNX-008 E: one LynxHost interface with a PrimJS adapter and a
fake test adapter. Native Module lookup, GlobalEventEmitter, platform,
text codec, fetch, and AbortController install go through src/host.ts.
LynxRemote transport stays in place (A deferred).

Co-authored-by: 達達 <djwok@users.noreply.github.com>
Replace the LynxRemote mega-module with a SyncStreamTransport seam and
three adapters: NativeHttpFetch (streamingId realtime primary),
LynxFetchModule fallback, and identifier fetch. Delete the FM-PS-LYNX-003
one-shot diagnostic in favor of PowerSync logger debug. Idle-complete stays
a fallback only (C deferred). Native HTTP module split is B, deferred.

Co-authored-by: 達達 <djwok@users.noreply.github.com>
…lete

Native sync HTTP lives in NativeSyncHttp (same Autolink lookup, not callNative).
Android and iOS emit onData* → onError? → onEnd. Idle-complete is the streamingId
fallback with one envelope and shared/sync_http_policy.h. Desktop N-API stays
SQL-only. ADR-0003 records the seam.

Co-authored-by: 達達 <djwok@users.noreply.github.com>
Presence-check httpFetch without type assertions; oxfmt the HTTP seam.

Co-authored-by: 達達 <djwok@users.noreply.github.com>
Replay one catalog (checkpoint+ops, error-then-end, idle-complete) through
native-http streamingId tests, Linux make test, make test-ios httpFetch,
and Android instrumentation so the B terminal sequence cannot drift.

Co-authored-by: 達達 <djwok@users.noreply.github.com>
D: Autolink NativePowerSyncModule SQL RPC is a thin Java/JNI binder over
shared ps_sql, dropping androidx.sqlite-bundled. Core still loads from the
Maven AAR via sqlite3_load_extension. NativeSyncHttp stays a separate
sub-interface.

G: iOS NativeSyncHttp no longer walks UIWindows for a LynxView. Hosts inject
sendGlobalEvent via setSharedStreamEventSender or initWithParam; missing
sender uses the idle-complete fallback.

Co-authored-by: 達達 <djwok@users.noreply.github.com>
JNI binder methods must survive consumer minification so SQL RPC stays on
shared ps_sql.

Co-authored-by: 達達 <djwok@users.noreply.github.com>
Lynx-for-Web always has lynx.getJSModule("GlobalEventEmitter"). identifier
streaming was discarding Response.body and waiting for native onData, so
A↔B download never applied. Keep a usable fetch body; streamingId still
uses GlobalEventEmitter. Read NativeModules as unknown to avoid TS2559.

Co-authored-by: 達達 <djwok@users.noreply.github.com>
Read the PrimJS bag through isNonNullObject and assert NativeModulesHost
at the lookup boundary so rspeedy typecheck stays green.

Co-authored-by: 達達 <djwok@users.noreply.github.com>
Co-authored-by: 達達 <djwok@users.noreply.github.com>
Do not declare NativeModules, TextCodecHelper, lynx, or SystemInfo on
the global namespace in src/globals.ts. @lynx-js/types already owns
those vars. PrimJS lookup uses module-local declare const plus a
globalThis probe so showcase pluginTypeCheck stays green.

Co-authored-by: 達達 <djwok@users.noreply.github.com>
Co-authored-by: 達達 <djwok@users.noreply.github.com>
Mac tip verify: NativeSyncHttp.mm failed to compile sendGlobalEvent on
untyped id (pod TU has no LynxView header). Declare PSLynxStreamEventSender
and cast after respondsToSelector. Android NDK AttachCurrentThread wants
JNIEnv**; keep OpenJDK void** behind !__ANDROID__ for make test.

Web download / host-fetch NDJSON path is unchanged.

Co-authored-by: 達達 <djwok@users.noreply.github.com>
@cursor
cursor Bot force-pushed the drkz/fm-ps-lynx-008-native-build-fix-4330 branch from 73f3b9c to 4ed232e Compare September 9, 2026 12:18
@cursor cursor Bot changed the title fix(native): iOS sendGlobalEvent compile + Android NDK AttachEnv FM-PS-LYNX-008: architecture stack + verify fixes Sep 9, 2026
@cursor

cursor Bot commented Sep 9, 2026

Copy link
Copy Markdown

Superseding this stacked PR: GitHub refused base: main (Cannot change the base branch because the pull request is part of a stack). Closing so the same tip branch can open a single PR into main with the full remaining FM-PS-LYNX-008 stack (E→A→B+C→F→D+G + web download + native build fix), rebased onto current main after #23.

@cursor

cursor Bot commented Sep 9, 2026

Copy link
Copy Markdown

Replaced by #32 (same tip branch, now targeting main). GitHub would not retarget this stacked PR.

@darekaze
darekaze deleted the drkz/fm-ps-lynx-008-native-build-fix-4330 branch September 9, 2026 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants