create-mithril-lynx 2.4.0 → 2.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -32,29 +32,146 @@ npm install
32
32
  npm run android # bundle -> assets -> installDebug -> launch on the device
33
33
  ```
34
34
 
35
+ ### With Android connectors
36
+
37
+ Android projects can opt into the published
38
+ [`lynx-android-plugins`](https://github.com/carlos-sweb/lynx-android-plugins)
39
+ artifacts at scaffold time. The generator adds the selected Maven libraries,
40
+ their JavaScript facade packages, manifest contributions, native-module
41
+ registrations, and the Activity callbacks required for camera and geolocation.
42
+
43
+ ```bash
44
+ npx create-mithril-lynx my-app --blank --android \
45
+ --android-plugins battery,geolocation,network
46
+ ```
47
+
48
+ Available connector names are `battery`, `camera`, `device`, `geolocation`,
49
+ `network`, `vibration`, `maps`, `sqlite`, and `all`. The interactive Android flow offers the
50
+ same selection. `all` deliberately includes every manifest contribution;
51
+ prefer individual names for production apps.
52
+
53
+ The generated Android host declares Maven Central dependencies at version
54
+ `0.4.0`, including `io.github.carlos-sweb:lynx-android-plugins:0.4.0` for `all`
55
+ and the individual connector artifacts when selecting specific names.
56
+ Adding or removing connectors also upgrades managed dependencies from the
57
+ previous template versions (`0.2.0`, or `0.3.0` for SQLite and `all`).
58
+
59
+ The generated project receives the `lynx-android-plugins` JavaScript package
60
+ with a small typed API for each selected feature. For example,
61
+ `import { gps } from "lynx-android-plugins/geolocation"`
62
+ followed by `await gps.get({ highAccuracy: true })` returns one location.
63
+ See the [JavaScript facades](https://github.com/carlos-sweb/lynx-android-plugins#javascript-facades)
64
+ for the complete API.
65
+
66
+ For offline maps, select `--android-plugins maps` (or add `maps` after
67
+ scaffolding). This creates `android/maps.json`. Supply the HTTPS URL, SHA-256,
68
+ and version of a Chile PMTiles archive there. Every build runs
69
+ `android:prepare` first and copies that config into the Android host. Import
70
+ `Maps` from `lynx-android-plugins/maps` and render it inside a sized parent:
71
+
72
+ ```ts
73
+ import { Maps } from "lynx-android-plugins/maps";
74
+ m(Maps, { latitude: -33.532290, longitude: -71.584904, variant: "full" });
75
+ ```
76
+
77
+ The map is downloaded only when the user taps the native download button.
78
+ Afterward it renders offline. The archive must be hosted by the app developer;
79
+ this project does not offer a public map-tile service. The Maps module is
80
+ prepared for Maven/npm version `0.2.0` and is not usable from the published
81
+ `0.1.0` artifacts.
82
+
83
+ For app-private SQLite storage, select `sqlite` and import
84
+ `sqlite` from `lynx-android-plugins/sqlite`. Calls are asynchronous and run in
85
+ the generated Android host; they do not run in stock Lynx Go. See the
86
+ [SQLite connector guide](https://github.com/carlos-sweb/lynx-android-plugins/blob/main/docs/sqlite.md)
87
+ for SQL parameters, migrations, transactions, and result types. The generated
88
+ host uses Maven version `0.4.0` for SQLite and `all`, and installs the JavaScript
89
+ facade from the latest npm release of `lynx-android-plugins`.
90
+
91
+ ### Add connectors after scaffolding
92
+
93
+ Projects generated with this version can update their selected connectors
94
+ without recreating the app:
95
+
96
+ ```bash
97
+ cd my-app
98
+ npx create-mithril-lynx add-android-plugin battery,geolocation
99
+ npx create-mithril-lynx remove-android-plugin battery
100
+ npx create-mithril-lynx list-android-plugins
101
+ ```
102
+
103
+ The generator stores its selection in `android/connectors.json` and updates its
104
+ own Gradle dependency block, connector registry, and marked connector sections
105
+ of `MainActivity.kt`. It generates permission and activity callbacks only for
106
+ connectors that need them; with no connectors, it removes the generated
107
+ registry. It also adds or removes the `lynx-android-plugins` dependency in
108
+ `package.json` and runs the detected package manager's install command when
109
+ that dependency changes. Existing managed hosts are migrated when their old
110
+ generated connector code is unchanged. A custom facade version, a modified
111
+ managed block, or an older host without `android/connectors.json` causes the
112
+ command to stop before replacing those edits.
113
+ Use `--no-install` after an add/remove command to update configuration without
114
+ running the package manager immediately.
115
+ To refresh an existing host without changing its selection, add an already
116
+ enabled connector again (for example, `add-android-plugin battery --no-install`).
117
+
35
118
  The interactive prompt offers it too, and the literal `target=android` form works as well:
36
119
 
37
120
  ```bash
38
121
  npm create mithril-lynx@latest my-app target=android
39
122
  ```
40
123
 
41
- Every flag, in one table — `npx create-mithril-lynx --help` prints the same list:
124
+ ### CLI reference
125
+
126
+ These are the project-creation flags. Run `npx create-mithril-lynx --help` to
127
+ see them together with the post-scaffold commands below.
42
128
 
43
129
  | Flag | Effect |
44
130
  |---|---|
45
131
  | `<name>` (positional) | Project name, and the directory to create. Omit it and you're prompted. |
46
132
  | `--hello-world` / `--blank` / `--basic-activity` | Template to scaffold. Omit it and you're prompted. |
47
- | `--no-install` | Don't install dependencies (also skips that prompt). |
133
+ | `--no-install` | Skip dependency installation after scaffolding; also skips the install prompt. For connector commands, prevents the package manager from running. |
48
134
  | `-h`, `--help` | Print usage and exit. |
135
+ | `--with-ui` | Add `mithril-lynx-ui` and import its stylesheet. Offered during interactive setup; works independently of `--android`. |
49
136
  | `--android` / `--target android` / `--target=android` / `target=android` | Also scaffold the sibling `<name>-android/` Gradle project. |
50
137
  | `--android-id <id>` | `applicationId` / `namespace` (default `com.example.<name>`). |
51
138
  | `--app-name <name>` | Launcher label (default: the project name). |
139
+ | `--android-plugins <list>` | Android connectors to include: comma-separated `battery`, `camera`, `device`, `geolocation`, `network`, `vibration`, `maps`, `sqlite`, or `all`. Implies `--android`. |
52
140
  | `--with-font <file.ttf>` | Bundle the font into `src/assets/fonts/` and register it with `lynx.addFont()` in a loop. **DEV** (`npm run dev` / Lynx Go): `require()` inlines a `data:` URI so the font shows up in Explorer. **PROD** (`npm run build` / APK): `asset:///fonts/<file>` resolved by `AssetFontFaceLoader` on the host (keeps the bundle small — embedding `data:` URIs in the APK re-introduces the cold-start cost tracked in [lynx#9431](https://github.com/lynx-family/lynx/issues/9431)). Comma-separate for more than one file. |
53
141
  | `--find-font <term>` | Search [Fontsource](https://fontsource.org)'s catalog for `<term>`, prompt you to pick a family and one or more weights/styles, download each `.ttf`, and bundle them exactly like `--with-font`. Needs a real terminal (the picking is inherently interactive — use `--with-font <file.ttf>` in scripts/CI). Mutually exclusive with `--with-font`. Comma-separate terms for more than one — quote the whole thing if any term has a space. |
54
142
  | `--font-family <name>` | Override the family name derived from the font's file name (or from Fontsource, with `--find-font`). Only valid with exactly one font. |
55
143
 
56
- Anything not listed — in particular the four Android flags — requires `--android`
57
- (or one of its aliases); `--with-font`/`--find-font` imply it on their own.
144
+ `--android-id` and `--app-name` configure the host when one is generated.
145
+ `--android-plugins` and the font flags imply `--android`; `--with-ui` works
146
+ with or without the Android host.
147
+
148
+ During interactive Android setup, the CLI asks whether to add fonts. If you
149
+ choose yes, search Fontsource, select a family and its variants, then choose
150
+ whether to add another font. The setup continues after you answer no. The
151
+ `--find-font` flag remains available for scripted scaffolding.
152
+
153
+ ### Commands for an existing project
154
+
155
+ Run these from the generated app directory. Connector commands require an
156
+ Android host created by this tool and manage only the generated connector
157
+ configuration.
158
+
159
+ | Command | Arguments and options | Effect |
160
+ |---|---|---|
161
+ | `add-font` | `--with-font <file.ttf>` or `--find-font <term>`; optional `--font-family <name>` | Add fonts to the existing app and wire up the generated font registration and CSS. Font options are the same as during scaffolding. |
162
+ | `add-android-plugin` | `<list>`; optional `--no-install` | Add comma-separated Android connectors (the same names as `--android-plugins`) and update dependencies. `--no-install` leaves dependency installation to you. |
163
+ | `remove-android-plugin` | `<list>`; optional `--no-install` | Remove managed connectors and update dependencies. If `all` is enabled, remove `all` as a whole. |
164
+ | `list-android-plugins` | — | Show the connectors currently enabled for the Android host. |
165
+
166
+ ### UI components
167
+
168
+ Add `mithril-lynx-ui` to a new app and import its stylesheet with:
169
+
170
+ ```bash
171
+ npx create-mithril-lynx my-app --blank --with-ui
172
+ ```
173
+
174
+ For component APIs and styling, see the [`mithril-lynx-ui` documentation](https://github.com/carlos-sweb/mithril-lynx-ui#readme).
58
175
 
59
176
  ### More than one font
60
177
 
@@ -124,8 +241,9 @@ The sibling `<name>-android/` project is a complete, no-Android-Studio Gradle CL
124
241
 
125
242
  - the Gradle wrapper (`gradlew`, `gradlew.bat`, `gradle-wrapper.jar`), so nothing needs to be installed besides a JDK and the Android SDK;
126
243
  - `local.properties` with `sdk.dir` auto-detected from `ANDROID_HOME`/`ANDROID_SDK_ROOT` (with a written warning if it can't be found);
127
- - the Kotlin host: the `Application` (registers `AssetFontFaceLoader`), `MainActivity` (async `AssetTemplateProvider`, splash screen, `NoopGenericResourceFetcher` for the fast `data:` font path — [lynx#9431](https://github.com/lynx-family/lynx/issues/9431));
128
- - resource files that compile as-is (theme, splash theme, adaptive launcher icon);
244
+ - the Kotlin host: the `Application` (registers `AssetFontFaceLoader`), `MainActivity` (async `AssetTemplateProvider`, splash screen, `NoopGenericResourceFetcher` for the fast `data:` font path — [lynx#9431](https://github.com/lynx-family/lynx/issues/9431)), and a predefined native bridge for `mithril-lynx/route`'s Android system Back support;
245
+ - a project-local `android/` folder with editable `AndroidManifest.xml`, `strings.xml`, `styles.xml`, `config.xml`, `network_security_config.xml`, and `file_paths.xml`, plus `bun run android:prepare` to copy them into the Gradle host;
246
+ - opt-in Maven Central connectors for battery, camera, device, geolocation, network, vibration, maps, and SQLite, each registered only when selected with `--android-plugins`;
129
247
  - an opt-in release signing setup driven by a gitignored `keystore.properties`.
130
248
 
131
249
  And in the JS project, a `scripts/android.mjs` bridge plus npm scripts:
@@ -135,10 +253,11 @@ npm run android # build + sync + installDebug + launch, printing Tota
135
253
  npm run android:apk # build + sync + assembleDebug
136
254
  npm run android:release # build + sync + assembleRelease (signed if keystore.properties exists)
137
255
  npm run android:sync # build + sync bundle into app/src/main/assets/, no Gradle
256
+ bun run android:prepare # manually sync android/*.xml and maps.json -> sibling Android host
138
257
  npm run android:keystore # generate release.keystore + keystore.properties (KEYSTORE_PASSWORD=...)
139
258
  ```
140
259
 
141
- This part of the tool is framework-agnostic — it just wraps whatever bundle `rspeedy build` produces into a native host — so it needed no changes for the `mithril-lynx` rewrite beyond what's inherited automatically through the generated JS project.
260
+ The packaging path still wraps whatever bundle `rspeedy build` produces. Its one framework-aware convenience is the predefined, otherwise dormant system Back bridge used by `mithril-lynx/route`; the Basic Activity template connects it automatically.
142
261
 
143
262
  ## Templates
144
263
 
@@ -146,7 +265,7 @@ This part of the tool is framework-agnostic — it just wraps whatever bundle `r
146
265
  |---|---|
147
266
  | **Hello World** (recommended) | The Mithril.js analog of Lynx's official React hello-world ([`lynx-examples/examples/hello-world`](https://github.com/lynx-family/lynx-examples/tree/main/examples/hello-world)) — same layout, same "tap the logo" interaction, running through Mithril hyperscript instead of JSX. |
148
267
  | **Blank** | A single centered line of text. Nothing else — the starting point when you don't want any of Hello World's styling/assets in your way. |
149
- | **Basic Activity** | Two screens (Main → Details) wired with [`mithril-lynx/route`](https://github.com/carlos-sweb/mithril-lynx/blob/main/ROUTE.md) — an in-memory router (`m.route`, reimplemented for an environment with no URL bar). Includes a reusable app-bar-with-back-button pattern, using `route.back()` since Lynx has no hardware back button for a route to hook into automatically. |
268
+ | **Basic Activity** | Two screens (Main → Details) wired with [`mithril-lynx/route`](https://github.com/carlos-sweb/mithril-lynx/blob/main/ROUTE.md) — an in-memory router (`m.route`, reimplemented for an environment with no URL bar). Includes a reusable app-bar back affordance and, with `--android`, predefined system Back/predictive Back integration through `route.listenBackButton()`. |
150
269
 
151
270
  ## Package structure
152
271
 
@@ -172,15 +291,35 @@ create-mithril-lynx/
172
291
  ts/src/{app-bar.ts, background.ts, screens/{home,detail}.ts}
173
292
  android/ only used with --android
174
293
  host/ the Gradle project -> <name>-android/
175
- (includes AssetFontFaceLoader +
176
- NoopGenericResourceFetcher for lynx#9431)
177
- app-scripts/android.mjs the bridge -> <name>/scripts/android.mjs
178
- (syncs bundle + src/assets/fonts/ → assets/fonts/)
294
+ (includes AssetFontFaceLoader,
295
+ NoopGenericResourceFetcher for lynx#9431, and the
296
+ MithrilLynxNavigationModule system-Back bridge)
297
+ app-scripts/{android,android-prepare}.mjs
298
+ bridges in <name>/scripts/ (syncs bundle/fonts;
299
+ prepares <name>/android/*.xml into the host)
179
300
  ```
180
301
 
181
302
  `src/index.js` copies, in order, `templates/_shared/common` → `templates/_shared/ts` → `templates/<template>/common` → `templates/<template>/ts` into the target directory — later copies overwrite same-named files from earlier ones, which is exactly how **Basic Activity**'s own routing-based `src/background.ts` replaces `_shared/ts`'s generic single-view one (Hello World and Blank don't ship their own, so they keep the shared file). It then renames `gitignore` to `.gitignore` (npm doesn't publish dotfiles reliably otherwise) and replaces `{{PROJECT_NAME}}`/`{{MITHRIL_LYNX_VERSION}}` placeholders in `package.json` and `README.md`.
182
303
 
183
- With `--android` it then copies `templates/android/host` into a sibling `<name>-android/` (renaming `package-path` to the real package directory and `App.kt` to the Application class) and substitutes `{{PACKAGE_NAME}}`, `{{APP_CLASS}}`, `{{APP_NAME}}`, `{{ANDROID_DIR}}` and `{{SDK_DIR}}` across the tree. Binary files (the Gradle wrapper jar, a `--with-font` `.ttf`) are never text-substituted. With `--with-font`, each font is copied into the JS project (`src/assets/fonts/`) *and* seeded into the Android host's `assets/fonts/`, wired up with a `FONTS` loop + `lynx.addFont()` in `src/background.ts` plus a generated `src/fonts.css` (`text { font-family }` for the first font, one class per font when there are several) imported from `src/style.css`. `scripts/android.mjs` keeps `assets/fonts/` in sync on every `npm run android` / `android:sync`.
304
+ Scaffolding handles the Android host and fonts as follows:
305
+
306
+ 1. **Android host (`--android`)**
307
+ - Copies `templates/android/host` into a sibling `<name>-android/` project.
308
+ - Renames `package-path` to the generated package directory and `App.kt` to the application class.
309
+ - Replaces `{{PACKAGE_NAME}}`, `{{APP_CLASS}}`, `{{APP_NAME}}`, `{{ANDROID_DIR}}` and `{{SDK_DIR}}` placeholders.
310
+ - Seeds the app's editable `android/` folder with `AndroidManifest.xml`, `strings.xml`, `styles.xml`, `config.xml`, `network_security_config.xml` and `file_paths.xml`.
311
+
312
+ 2. **Android preparation**
313
+ - `bun run build` and Android build commands run `android:prepare` before building, copying the editable config files into the Gradle host.
314
+ - To copy the files without building, run `bun run android:prepare` (or `npm run android:prepare`).
315
+
316
+ 3. **Fonts (`--with-font`)**
317
+ - Copies each `.ttf` into `src/assets/fonts/` and registers it from `src/background.ts` with a generated `FONTS` loop and `lynx.addFont()`.
318
+ - Generates `src/fonts.css`, imported by `src/style.css`; it sets the first font as the default `text` font and creates a class for each font variant.
319
+ - When an Android host exists, also copies fonts into its `assets/fonts/`. `scripts/android.mjs` syncs that folder during `npm run android` and `npm run android:sync`.
320
+
321
+ 4. **Binary files**
322
+ - The Gradle wrapper JAR and font `.ttf` files are copied as binary assets; placeholder substitution does not modify them.
184
323
 
185
324
  **Not carried over from v1 (yet)**: the JavaScript variant. The old tool generated either TypeScript or JavaScript for every template; this rewrite ships TypeScript only for now — doubling every template for a parallel JS copy wasn't part of this pass.
186
325
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-mithril-lynx",
3
- "version": "2.4.0",
3
+ "version": "2.5.2",
4
4
  "description": "Scaffolds a new mithril-lynx app (and, optionally, its Android host).",
5
5
  "license": "MIT",
6
6
  "type": "module",