feat: NativeScript support - #11
Open
NathanWalker wants to merge 8 commits into
Open
NathanWalker wants to merge 8 commits into
NathanWalker wants to merge 8 commits into
Conversation
A `nativescript` route provider, one module with a flavour per framework.
Angular follows provideNativeScriptRouter(routes) into every loadChildren
module and reads named outlets, redirectTo aliases, enum-valued paths and
barrel re-exports; a route with children is a layout (tabs when its
children sit in several named outlets), and edges come from navigate([]),
navigateByUrl() and nsRouterLink with relativeTo honoured. Core reads
<Page> XML files and Frame.navigate({ moduleName }). Octane, React, Vue,
Svelte and Solid have no route table, so a screen is a component the
framework mounts, pushes, presents, hosts in a <frame> tab, or registers
in a solid-navigation <Route> table; each flavour is one row of spellings
over a shared engine.
No flavour has a linking config: the app registers a URL scheme in
App_Resources and maps URLs onto navigation in its own code. Every route
therefore starts navigation-only and .screenmap/config.json's routes.links
names the ones a link opens. The scheme, app id and name come from
nativescript.config.ts, Info.plist (xcconfig variables resolved) and
AndroidManifest.xml, and a provider can now replace the graph's
deepLinkTemplates, since Expo Go means nothing here.
Validated against five real apps (a 54-screen Angular app, an Octane chat
app, and Angular, Vue and Solid Apple Music clones); six fixtures pin the
graphs. The test runner keeps a fixture's committed .screenmap/config.json.
…stub A NativeScript app ships its JavaScript inside the .app or .apk, so the session installs and launches the build and that is the whole boot: no Metro, no dev-client nudging, no dev-menu muting. The runtime is detected from nativescript.config.* and builds are found under platforms/. An app that registers no URL scheme no longer fails the run: its root is captured by launching, and only the rest waits for flows or the agent. Under @nativescript/vite, `ns debug` writes a stub bundle whose @nativescript/core imports are http://<host>:5173/ns/core URLs; headless it dies on the first import and every capture is the simulator home screen, which is what the first Octane run produced. The session now reads app/bundle.mjs and fails with the dev-server origin and the `ns build` command instead.
The skill gets the NativeScript boot steps (ns build, not ns debug), the routes.links overlay, the no-scheme case, and the drawer, native-menu and ns-modal hints. The README gains a NativeScript section and the config table the runtime, routes.provider and routes.links keys; the provider guide documents the flavour table and the frame-hosting and router-shell rules. TODOS records what the first pass verified and what it did not.
flowResolution built an open_url matcher for every node, and a navigation-only screen has no urlPath to split, so the Graph component threw on the first NativeScript bundle and would have on any react-navigation map with a screen outside its linking config. Such a screen has no URL an open_url step could land on, so it simply gets no matcher.
Chrome 152 refuses an https page a fetch to http://localhost unless the user grants local network access, so the hosted viewer never received the bundle and the shot timed out on its readiness flag. The one headless browser the renderer launches now has that check switched off.
?shot=captured drops every screen without a good capture before laying the map out, so an image of a map the deterministic lane reached only part of shows the screens it has instead of a wall of placeholders; `screenmap-ci shot --mode captured` asks for it. findBuiltApp preferred the Debug directory, which on a project holding both a Debug and a Release build of the same app meant the older one. The build most recently written wins now, on both platforms — a Solid app whose debug build halts on a dev-only reactivity assertion renders from `ns build ios --release`, and that is the build meant.
Twenty-two hand-recorded argent flows replayed with every landmark check passing across the Octane, Vue, Angular and Solid apps, and Solid renders from a release build; TODOS moves both out of the unverified list.
The fixture depended on svelte-native, the package's old name; the maintained one is @nativescript-community/svelte-native. Both name the Svelte flavour now, since older apps still carry the old dependency.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
NativeScript support: Core, Octane, React, Vue, Svelte, Solid and Angular apps
screenmap now maps NativeScript apps, whichever framework drives the views, and runs them through the same capture, pack, diff and viewer pipeline as an Expo app. Five commits, each self-contained:
nativescriptroute provider with one flavour per framework.<Page>XML files andFrame.navigate({ moduleName })/showModal().<frame>tab, or registers in asolid-navigation<Route>table. One shared engine, one row of spellings per flavour.App_Resourcesand maps URLs onto navigation in its own code. Every route starts navigation-only androutes.linksin.screenmap/config.jsonnames the ones a deep link opens. Scheme, app id and name are read fromnativescript.config.ts,Info.plist(xcconfig variables resolved) andAndroidManifest.xml.provideNativeScriptRouter(routes)into everyloadChildrenmodule; reads named outlets,redirectToaliases, enum-valued paths, barrel re-exports; a route withchildrenis a layout (tabs when its children sit in several named outlets); edges fromnavigate([...]),navigateByUrl()andnsRouterLink, withrelativeTohonoured..app/.apk, so the session installs and launches it and that is the whole boot. Builds are found underplatforms/. An app with no URL scheme has its root captured by launching. Ans debugbuild under@nativescript/vite(a stub that imports core from the dev server) is refused with the dev-server origin and thens buildcommand, instead of silently capturing the simulator home screen.flowResolutionbuilt anopen_urlmatcher for every node and split a nullurlPath; any react-navigation map with a screen outside its linking config would have crashed the same way.Validated against real apps
listen-nowas the landing/<Route>table, router shell read as a layoutns build(app-side, see below)Detection scores 0.95 on all five with nothing else above 0.10. Nine fixtures pin the graphs (
node fixtures/run-tests.mjs).Each image below is the map viewer showing the packed
.scrmapfrom one run (screenmap-ci shot), deterministic lane only, no agent: captured screens are real screenshots, the rest are navigation-only and wait for flows or the agent.Octane — the chat root and the settings sheet it presents as a second Octane root.
Angular — five named-outlet tabs read as
Tabs, the album screen reached from four of them.Vue — the same app in Vue: tab screens hosted in
<Frame>s underHome,$navigateToand$showModaledges.Solid —
solid-navigation's<Route>table andnavigate('Album')by name. The black root is the app itself: a plainns build iosof it halts at launch with Solid'sREACTIVITY_HALTEDthrown fromsolid-navigation, so it only runs under its HMR session.HeyKiddo Talk (Angular) — 54 screens, 20 reached by deep link through the app's own
com.heykiddo.talk://handler.For reviewers
.app/.apkasapp_path; the EAS lane andexpo_tokendo not apply.routes.providerpins the provider when detection is wrong;routes.linksis the deep-link overlay. Both are in the config table in the README.