@axonpack/preview 0.0.0-stage → 0.1.0
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/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/README.md +118 -2
- package/android/build.gradle +21 -0
- package/android/consumer-rules.pro +3 -0
- package/android/src/main/java/expo/modules/axonpackpreview/AxonpackPreviewModule.kt +72 -0
- package/android/src/main/java/expo/modules/axonpackpreview/BundleLoaderOverride.kt +41 -0
- package/android/src/main/java/expo/modules/axonpackpreview/HermesHeader.kt +24 -0
- package/android/src/main/java/expo/modules/axonpackpreview/PreviewPackage.kt +76 -0
- package/android/src/main/java/expo/modules/axonpackpreview/PreviewState.kt +295 -0
- package/app.plugin.js +112 -0
- package/bin/preview.js +2 -0
- package/build/cli.cjs +1465 -0
- package/build/cli.d.ts +3 -0
- package/build/cli.d.ts.map +1 -0
- package/build/cli.js +164 -0
- package/build/cli.js.map +1 -0
- package/build/components/preview-list/preview-list.component.d.ts +13 -0
- package/build/components/preview-list/preview-list.component.d.ts.map +1 -0
- package/build/components/preview-list/preview-list.component.js +316 -0
- package/build/components/preview-list/preview-list.component.js.map +1 -0
- package/build/components/preview-list/preview-list.types.d.ts +59 -0
- package/build/components/preview-list/preview-list.types.d.ts.map +1 -0
- package/build/components/preview-list/preview-list.types.js +2 -0
- package/build/components/preview-list/preview-list.types.js.map +1 -0
- package/build/components/preview-provider/preview-provider.component.d.ts +12 -0
- package/build/components/preview-provider/preview-provider.component.d.ts.map +1 -0
- package/build/components/preview-provider/preview-provider.component.js +19 -0
- package/build/components/preview-provider/preview-provider.component.js.map +1 -0
- package/build/constants/dev-preview-servers/dev-preview-servers.const.d.ts +26 -0
- package/build/constants/dev-preview-servers/dev-preview-servers.const.d.ts.map +1 -0
- package/build/constants/dev-preview-servers/dev-preview-servers.const.js +9 -0
- package/build/constants/dev-preview-servers/dev-preview-servers.const.js.map +1 -0
- package/build/constants/preview-list/theme.const.d.ts +5 -0
- package/build/constants/preview-list/theme.const.d.ts.map +1 -0
- package/build/constants/preview-list/theme.const.js +65 -0
- package/build/constants/preview-list/theme.const.js.map +1 -0
- package/build/index.d.ts +24 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +16 -0
- package/build/index.js.map +1 -0
- package/build/services/cli/config.service.d.ts +13 -0
- package/build/services/cli/config.service.d.ts.map +1 -0
- package/build/services/cli/config.service.js +39 -0
- package/build/services/cli/config.service.js.map +1 -0
- package/build/services/cli/project.service.d.ts +25 -0
- package/build/services/cli/project.service.d.ts.map +1 -0
- package/build/services/cli/project.service.js +81 -0
- package/build/services/cli/project.service.js.map +1 -0
- package/build/services/cli/title.service.d.ts +15 -0
- package/build/services/cli/title.service.d.ts.map +1 -0
- package/build/services/cli/title.service.js +24 -0
- package/build/services/cli/title.service.js.map +1 -0
- package/build/services/dev-preview-servers/discover.service.d.ts +14 -0
- package/build/services/dev-preview-servers/discover.service.d.ts.map +1 -0
- package/build/services/dev-preview-servers/discover.service.js +106 -0
- package/build/services/dev-preview-servers/discover.service.js.map +1 -0
- package/build/services/native/build-info.service.d.ts +11 -0
- package/build/services/native/build-info.service.d.ts.map +1 -0
- package/build/services/native/build-info.service.js +18 -0
- package/build/services/native/build-info.service.js.map +1 -0
- package/build/services/native/native.service.d.ts +24 -0
- package/build/services/native/native.service.d.ts.map +1 -0
- package/build/services/native/native.service.js +13 -0
- package/build/services/native/native.service.js.map +1 -0
- package/build/services/previews/download.service.d.ts +14 -0
- package/build/services/previews/download.service.d.ts.map +1 -0
- package/build/services/previews/download.service.js +66 -0
- package/build/services/previews/download.service.js.map +1 -0
- package/build/services/previews/local-previews.service.d.ts +25 -0
- package/build/services/previews/local-previews.service.d.ts.map +1 -0
- package/build/services/previews/local-previews.service.js +50 -0
- package/build/services/previews/local-previews.service.js.map +1 -0
- package/build/services/previews/reload.service.d.ts +6 -0
- package/build/services/previews/reload.service.d.ts.map +1 -0
- package/build/services/previews/reload.service.js +13 -0
- package/build/services/previews/reload.service.js.map +1 -0
- package/build/services/previews/remote.service.d.ts +11 -0
- package/build/services/previews/remote.service.d.ts.map +1 -0
- package/build/services/previews/remote.service.js +34 -0
- package/build/services/previews/remote.service.js.map +1 -0
- package/build/services/previews/select.service.d.ts +11 -0
- package/build/services/previews/select.service.d.ts.map +1 -0
- package/build/services/previews/select.service.js +25 -0
- package/build/services/previews/select.service.js.map +1 -0
- package/build/services/previews/use-preview.service.d.ts +21 -0
- package/build/services/previews/use-preview.service.d.ts.map +1 -0
- package/build/services/previews/use-preview.service.js +24 -0
- package/build/services/previews/use-preview.service.js.map +1 -0
- package/build/services/previews/use-running.service.d.ts +4 -0
- package/build/services/previews/use-running.service.d.ts.map +1 -0
- package/build/services/previews/use-running.service.js +21 -0
- package/build/services/previews/use-running.service.js.map +1 -0
- package/build/services/publish/bundle.service.d.ts +11 -0
- package/build/services/publish/bundle.service.d.ts.map +1 -0
- package/build/services/publish/bundle.service.js +46 -0
- package/build/services/publish/bundle.service.js.map +1 -0
- package/build/services/publish/commands.service.d.ts +23 -0
- package/build/services/publish/commands.service.d.ts.map +1 -0
- package/build/services/publish/commands.service.js +130 -0
- package/build/services/publish/commands.service.js.map +1 -0
- package/build/services/publish/eas-env.service.d.ts +9 -0
- package/build/services/publish/eas-env.service.d.ts.map +1 -0
- package/build/services/publish/eas-env.service.js +49 -0
- package/build/services/publish/eas-env.service.js.map +1 -0
- package/build/services/registry/registry.service.d.ts +27 -0
- package/build/services/registry/registry.service.d.ts.map +1 -0
- package/build/services/registry/registry.service.js +89 -0
- package/build/services/registry/registry.service.js.map +1 -0
- package/build/services/s3/s3.service.d.ts +59 -0
- package/build/services/s3/s3.service.d.ts.map +1 -0
- package/build/services/s3/s3.service.js +154 -0
- package/build/services/s3/s3.service.js.map +1 -0
- package/build/services/start/start.service.d.ts +48 -0
- package/build/services/start/start.service.d.ts.map +1 -0
- package/build/services/start/start.service.js +172 -0
- package/build/services/start/start.service.js.map +1 -0
- package/build/stores/dev-preview-servers/dev-preview-servers.store.d.ts +21 -0
- package/build/stores/dev-preview-servers/dev-preview-servers.store.d.ts.map +1 -0
- package/build/stores/dev-preview-servers/dev-preview-servers.store.js +91 -0
- package/build/stores/dev-preview-servers/dev-preview-servers.store.js.map +1 -0
- package/build/stores/previews/previews.store.d.ts +36 -0
- package/build/stores/previews/previews.store.d.ts.map +1 -0
- package/build/stores/previews/previews.store.js +134 -0
- package/build/stores/previews/previews.store.js.map +1 -0
- package/build/utils/config/config.util.d.ts +39 -0
- package/build/utils/config/config.util.d.ts.map +1 -0
- package/build/utils/config/config.util.js +24 -0
- package/build/utils/config/config.util.js.map +1 -0
- package/build/utils/config/expo-config.util.d.ts +30 -0
- package/build/utils/config/expo-config.util.d.ts.map +1 -0
- package/build/utils/config/expo-config.util.js +43 -0
- package/build/utils/config/expo-config.util.js.map +1 -0
- package/build/utils/dev-preview-servers/merge-servers.util.d.ts +47 -0
- package/build/utils/dev-preview-servers/merge-servers.util.d.ts.map +1 -0
- package/build/utils/dev-preview-servers/merge-servers.util.js +37 -0
- package/build/utils/dev-preview-servers/merge-servers.util.js.map +1 -0
- package/build/utils/preview-list/theme.util.d.ts +5 -0
- package/build/utils/preview-list/theme.util.d.ts.map +1 -0
- package/build/utils/preview-list/theme.util.js +12 -0
- package/build/utils/preview-list/theme.util.js.map +1 -0
- package/build/utils/previews/layout.util.d.ts +89 -0
- package/build/utils/previews/layout.util.d.ts.map +1 -0
- package/build/utils/previews/layout.util.js +30 -0
- package/build/utils/previews/layout.util.js.map +1 -0
- package/build/utils/previews/preview-items.util.d.ts +23 -0
- package/build/utils/previews/preview-items.util.d.ts.map +1 -0
- package/build/utils/previews/preview-items.util.js +39 -0
- package/build/utils/previews/preview-items.util.js.map +1 -0
- package/build/utils/previews/preview-title.util.d.ts +2 -0
- package/build/utils/previews/preview-title.util.d.ts.map +1 -0
- package/build/utils/previews/preview-title.util.js +6 -0
- package/build/utils/previews/preview-title.util.js.map +1 -0
- package/build/utils/previews/running.util.d.ts +23 -0
- package/build/utils/previews/running.util.d.ts.map +1 -0
- package/build/utils/previews/running.util.js +23 -0
- package/build/utils/previews/running.util.js.map +1 -0
- package/build/utils/publish/changelog.util.d.ts +5 -0
- package/build/utils/publish/changelog.util.d.ts.map +1 -0
- package/build/utils/publish/changelog.util.js +19 -0
- package/build/utils/publish/changelog.util.js.map +1 -0
- package/build/utils/publish/indexes.util.d.ts +12 -0
- package/build/utils/publish/indexes.util.d.ts.map +1 -0
- package/build/utils/publish/indexes.util.js +52 -0
- package/build/utils/publish/indexes.util.js.map +1 -0
- package/build/utils/s3/sigv4.util.d.ts +24 -0
- package/build/utils/s3/sigv4.util.d.ts.map +1 -0
- package/build/utils/s3/sigv4.util.js +67 -0
- package/build/utils/s3/sigv4.util.js.map +1 -0
- package/expo-module.config.json +10 -0
- package/ios/AxonpackPreview.podspec +30 -0
- package/ios/AxonpackPreviewModule.swift +55 -0
- package/ios/PreviewReactDelegateHandler.swift +147 -0
- package/ios/PreviewState.swift +236 -0
- package/notes/README.md +36 -0
- package/notes/bundles.md +35 -0
- package/notes/dev-preview-servers.md +67 -0
- package/notes/distribution.md +138 -0
- package/notes/native-loader.md +56 -0
- package/notes/storage.md +145 -0
- package/notes/testing.md +97 -0
- package/package.json +107 -4
package/notes/storage.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Storage
|
|
2
|
+
|
|
3
|
+
Where previews are kept: in the bucket they are published to, and on the device once downloaded.
|
|
4
|
+
|
|
5
|
+
- [ ] Reads previews from any S3-compatible bucket (S3, R2, MinIO and others), public or private (with a read-only key)
|
|
6
|
+
- [ ] Downloads a preview into the app's documents folder and checks every file
|
|
7
|
+
- [ ] Keeps a download until QA deletes it; nothing expires on a timer
|
|
8
|
+
- [ ] Shows downloads made for another native build apart, with one button to delete them all
|
|
9
|
+
|
|
10
|
+
A half-finished download is never offered, because it only becomes a preview once every file has
|
|
11
|
+
been checked.
|
|
12
|
+
|
|
13
|
+
## Settings
|
|
14
|
+
|
|
15
|
+
Publishing reads its settings the way Expo reads the app's: from the environment, then the same
|
|
16
|
+
`.env*` files Expo loads for a release bundle. Only `EXPO_PUBLIC_*` values are built into the app,
|
|
17
|
+
so the write key, which has no such prefix, never ends up inside it.
|
|
18
|
+
|
|
19
|
+
| Variable | Read by | What it holds |
|
|
20
|
+
| -------------------------- | ----------------------------- | --------------------------------------------------------------------------------- |
|
|
21
|
+
| `PREVIEW_S3_*` | `preview publish` only | The bucket URL and the **write** key |
|
|
22
|
+
| `EXPO_PUBLIC_PREVIEW_S3_*` | Expo, when it bundles the app | The bucket URL and, for a private bucket, a **read-only** key. Built into the app |
|
|
23
|
+
|
|
24
|
+
The CLI never reads `EXPO_PUBLIC_*`. The example has `example/.env.example` (the app's settings)
|
|
25
|
+
and `example/.env.local.example` (the publish settings) with the local values.
|
|
26
|
+
|
|
27
|
+
### Publish settings
|
|
28
|
+
|
|
29
|
+
CI has no settings file, so the environment comes first: the shell, or the CI job's secrets. For
|
|
30
|
+
publishing from your own machine they can go in an env file instead. Publish loads the files
|
|
31
|
+
`expo export:embed --dev false` loads (mode `production`), through the app's own `@expo/env`, so the
|
|
32
|
+
order and the `${VAR}` expansion are Expo's:
|
|
33
|
+
|
|
34
|
+
1. `.env.production.local`
|
|
35
|
+
2. `.env.local`
|
|
36
|
+
3. `.env.production`
|
|
37
|
+
4. `.env`
|
|
38
|
+
|
|
39
|
+
A variable set in the environment wins over every file, and the first file in the list wins over
|
|
40
|
+
the ones after it. `.env.development*` and other modes are not read. `EXPO_NO_DOTENV` turns the
|
|
41
|
+
files off here too.
|
|
42
|
+
|
|
43
|
+
Put the write key in `.env.local` or `.env.production.local`, which Expo's project template
|
|
44
|
+
gitignores (`.env*.local`), or in CI secrets. Never put it in a committed `.env`: anyone with the
|
|
45
|
+
repo could then write to the bucket.
|
|
46
|
+
|
|
47
|
+
| Variable | Needed | What it is |
|
|
48
|
+
| ------------------------------ | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
49
|
+
| `PREVIEW_S3_URL` | yes | `<endpoint>/<bucket>`, plus a folder inside the bucket if there are more segments: `http://localhost:9000/previews-public`, `https://<account>.r2.cloudflarestorage.com/previews/my-app` |
|
|
50
|
+
| `PREVIEW_S3_ACCESS_KEY_ID` | yes | Write key id. Never ship it in the app |
|
|
51
|
+
| `PREVIEW_S3_SECRET_ACCESS_KEY` | yes | Write key secret |
|
|
52
|
+
| `PREVIEW_S3_REGION` | no | Signing region. Default `us-east-1`, which MinIO and R2 accept |
|
|
53
|
+
|
|
54
|
+
The names are the package's own, not `AWS_*`, so they work the same for any S3-compatible host and
|
|
55
|
+
never pick up AWS keys already exported in a shell.
|
|
56
|
+
|
|
57
|
+
## Set up local storage
|
|
58
|
+
|
|
59
|
+
For the whole run, from starting the server to switching previews in the app, see
|
|
60
|
+
[testing.md](./testing.md).
|
|
61
|
+
|
|
62
|
+
A local S3 server, so you can try both bucket modes without a cloud account. It is MinIO, with one
|
|
63
|
+
public-read bucket and one private bucket plus a read-only key. Every name, key and the port live in
|
|
64
|
+
`local-s3/local-s3.env`, and both setups below read that file. The keys are local test values only.
|
|
65
|
+
|
|
66
|
+
### With Docker (main path)
|
|
67
|
+
|
|
68
|
+
Needs Docker: Docker Desktop or OrbStack on macOS, the Docker engine on Linux. Podman's Docker
|
|
69
|
+
socket works too. From `packages/@axonpack/preview`:
|
|
70
|
+
|
|
71
|
+
| Command | Does |
|
|
72
|
+
| ----------------------------- | ---------------------------------------------------------------------- |
|
|
73
|
+
| `bun run storage:local` | Starts MinIO, then creates the buckets and the read key. Safe to rerun |
|
|
74
|
+
| `bun run storage:local:stop` | Stops it. Uploaded files stay in `local-s3/data/` (gitignored) |
|
|
75
|
+
| `bun run storage:local:reset` | Stops it and deletes `local-s3/data/`, so the next start is empty |
|
|
76
|
+
|
|
77
|
+
MinIO stopped publishing its own images in 2025, so `local-s3/compose.yaml` uses Bitnami's frozen
|
|
78
|
+
copies, pinned by digest.
|
|
79
|
+
|
|
80
|
+
### Without Docker
|
|
81
|
+
|
|
82
|
+
1. `brew install minio/stable/minio minio/stable/mc` (not tried here: MinIO's own downloads changed
|
|
83
|
+
in 2025, so this tap may be gone).
|
|
84
|
+
2. In one terminal, from `packages/@axonpack/preview/local-s3`:
|
|
85
|
+
`set -a; . ./local-s3.env; set +a; minio server ./data --address ":$LOCAL_S3_PORT"`
|
|
86
|
+
3. In another, from the same folder:
|
|
87
|
+
`set -a; . ./local-s3.env; set +a; LOCAL_S3_URL="http://localhost:$LOCAL_S3_PORT" sh ./init.sh`
|
|
88
|
+
|
|
89
|
+
`init.sh` is the same script the Docker setup runs, so the buckets, policy and key come out the same.
|
|
90
|
+
|
|
91
|
+
### What you get
|
|
92
|
+
|
|
93
|
+
| Value | Local test value |
|
|
94
|
+
| -------------- | ------------------------------------------------------------------------- |
|
|
95
|
+
| Endpoint | `http://localhost:9000`, region `us-east-1`, path-style URLs |
|
|
96
|
+
| Public bucket | `previews-public`: anyone can read, only the write key can write |
|
|
97
|
+
| Private bucket | `previews-private`: reads need the read key, signed with SigV4 |
|
|
98
|
+
| Write key | `preview-admin` / `preview-admin-secret` (MinIO's root user) |
|
|
99
|
+
| Read key | `preview-reader` / `preview-reader-secret` (read `previews-private` only) |
|
|
100
|
+
|
|
101
|
+
A file is at `<endpoint>/<bucket>/<path>`.
|
|
102
|
+
|
|
103
|
+
### The example app
|
|
104
|
+
|
|
105
|
+
The example reads its bucket from `example/.env` (copy `example/.env.example`):
|
|
106
|
+
|
|
107
|
+
| Variable | Needed | What it is |
|
|
108
|
+
| ----------------------------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
109
|
+
| `EXPO_PUBLIC_PREVIEW_S3_URL` | yes | With a read key, the same `<endpoint>/<bucket>` the previews are published to. Without one, any address they are public under: that URL, R2's `https://pub-<id>.r2.dev` or a CDN |
|
|
110
|
+
| `EXPO_PUBLIC_PREVIEW_S3_READ_ACCESS_KEY_ID` | no | Only for a private bucket: the read-only key (`preview-reader` locally) |
|
|
111
|
+
| `EXPO_PUBLIC_PREVIEW_S3_READ_SECRET_ACCESS_KEY` | no | Its secret (`preview-reader-secret` locally) |
|
|
112
|
+
| `EXPO_PUBLIC_PREVIEW_S3_REGION` | no | Signing region for a private bucket. Default `us-east-1`; `auto` on R2 |
|
|
113
|
+
|
|
114
|
+
With a read key the app splits the URL into endpoint, bucket and folder and signs its reads. Without
|
|
115
|
+
one it reads `<url>/<key>` unsigned, so the URL needs no bucket in it.
|
|
116
|
+
|
|
117
|
+
Headers for a tunnel or proxy are not env values: pass `headers` in the app's config.
|
|
118
|
+
|
|
119
|
+
Expo builds `EXPO_PUBLIC_*` values into the app, so only a read-only key may go there, never the
|
|
120
|
+
write key. They are read when the app is bundled, so rebuild after changing them.
|
|
121
|
+
|
|
122
|
+
The address `localhost:9000` works as it is on the iOS simulator. On the Android emulator, run
|
|
123
|
+
`adb reverse tcp:9000 tcp:9000` once per emulator start, so the emulator's `localhost:9000` reaches
|
|
124
|
+
this computer. On a phone, use the computer's LAN address instead (`http://<LAN IP>:9000/...`), in
|
|
125
|
+
both the publish URL and the app's URL.
|
|
126
|
+
|
|
127
|
+
A tunnel works too, for a phone on another network: forward port 9000 (a VS Code dev tunnel, for
|
|
128
|
+
example) and put its HTTPS address in the app's URL, while publishing stays on `localhost:9000`. The
|
|
129
|
+
tunnel must be public, or it answers every request with a redirect to a login page. Dev tunnels may
|
|
130
|
+
also put a warning page in front of the first request; pass
|
|
131
|
+
`headers: { "X-Tunnel-Skip-AntiPhishing-Page": "True" }` in the app's config to skip it.
|
|
132
|
+
|
|
133
|
+
### Plain HTTP on a device
|
|
134
|
+
|
|
135
|
+
The local server has no TLS. A release build on Android refuses plain HTTP to any host unless the
|
|
136
|
+
app allows cleartext traffic, so downloads fail with a cleartext error, while a debug build works.
|
|
137
|
+
The example app turns cleartext on in its own config (`expo-build-properties`,
|
|
138
|
+
`android.usesCleartextTraffic`), never in the package's defaults. A real app should use HTTPS. iOS does not apply App Transport Security to IP
|
|
139
|
+
addresses or `localhost`, so the simulator and a phone using the LAN IP should work as they are
|
|
140
|
+
(to be checked on a device in the download phase).
|
|
141
|
+
|
|
142
|
+
Android 17 also asks the user before an app may reach the local network, which includes the
|
|
143
|
+
emulator's `10.0.2.2` and a LAN IP (the `ACCESS_LOCAL_NETWORK` permission). If it is denied, both
|
|
144
|
+
downloads from the local server and a debug build's connection to Metro fail. On the emulator,
|
|
145
|
+
`adb shell pm grant <package> android.permission.ACCESS_LOCAL_NETWORK` grants it.
|
package/notes/testing.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Testing
|
|
2
|
+
|
|
3
|
+
Running the example end to end on your own machine, with no cloud account.
|
|
4
|
+
|
|
5
|
+
- [x] A local S3 server (MinIO) with a public and a private bucket, started with one command
|
|
6
|
+
- [x] An example app (the default `create-expo-app` template, tabs) with the list on a Previews tab
|
|
7
|
+
- [x] A banner on every tab that says what runs: a dev preview server, a preview, or the base bundle
|
|
8
|
+
- [x] Links that do what the list's buttons do, so a run can be scripted from a terminal
|
|
9
|
+
|
|
10
|
+
## Run the example end to end
|
|
11
|
+
|
|
12
|
+
From `packages/@axonpack/preview`, after `bun install` at the repo root.
|
|
13
|
+
|
|
14
|
+
1. Start Docker, or Podman with `podman machine start`.
|
|
15
|
+
2. Start the local S3 server:
|
|
16
|
+
```sh
|
|
17
|
+
bun run storage:local
|
|
18
|
+
```
|
|
19
|
+
3. Copy the two settings files. `.env` holds the app's settings. `.env.local` holds the publish
|
|
20
|
+
settings with the write key; uncomment its lines after copying. Both are gitignored.
|
|
21
|
+
```sh
|
|
22
|
+
cp example/.env.example example/.env
|
|
23
|
+
cp example/.env.local.example example/.env.local
|
|
24
|
+
```
|
|
25
|
+
4. Build and run the example, in a debug or a release build:
|
|
26
|
+
```sh
|
|
27
|
+
cd example
|
|
28
|
+
npx expo run:ios # or: npx expo run:ios --configuration Release
|
|
29
|
+
npx expo run:android # or: npx expo run:android --variant release
|
|
30
|
+
```
|
|
31
|
+
5. Make sure the device reaches the server:
|
|
32
|
+
- iOS simulator: `localhost` works as it is.
|
|
33
|
+
- Android emulator, or a phone on USB: `adb reverse tcp:9000 tcp:9000`, once each time the device
|
|
34
|
+
starts.
|
|
35
|
+
- Phone on the same Wi-Fi: put the computer's LAN IP in `EXPO_PUBLIC_PREVIEW_S3_URL`.
|
|
36
|
+
- Phone on another network: a public tunnel to port 9000 (see [storage.md](./storage.md#the-example-app)).
|
|
37
|
+
|
|
38
|
+
`EXPO_PUBLIC_*` values are built into the bundle, so after changing one run
|
|
39
|
+
`npx expo start --clear`, or rebuild for a release build.
|
|
40
|
+
|
|
41
|
+
6. Publish a preview from `example/`:
|
|
42
|
+
```sh
|
|
43
|
+
bun run publish:preview --id task-1-login-fix --changelog="- Fixes the login"
|
|
44
|
+
```
|
|
45
|
+
That publishes for Android and iOS. In a terminal it asks for the title, prefilled from the id;
|
|
46
|
+
Enter keeps it.
|
|
47
|
+
`bunx preview publish …` works too. Use `bunx` in this repo, not `npx`: `npx` can't read
|
|
48
|
+
bun's install, so it looks for a `preview` package on npm and fails with a 404. An app
|
|
49
|
+
installed with npm uses `npx`.
|
|
50
|
+
7. In the app's Previews tab: Refresh, Download, Switch, then Back to base. The banner at the top
|
|
51
|
+
names what runs. Publish the same id again with other
|
|
52
|
+
changes to see "Update available", or `bunx preview unpublish <id>` to see "Unpublished".
|
|
53
|
+
8. Stop everything:
|
|
54
|
+
```sh
|
|
55
|
+
cd .. && bun run storage:local:stop
|
|
56
|
+
podman machine stop # if you use Podman
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The example also takes links, which run the same code as its buttons:
|
|
60
|
+
`previewexample://download/<id>`, `switch/<id>`, `switch/embedded`, `refresh`, `delete/<id>`,
|
|
61
|
+
`deleteincompatible`, `local/<port>` and `localstop`. Each one lands on the Previews tab
|
|
62
|
+
(`src/app/+native-intent.tsx`). Open them with `xcrun simctl openurl booted <link>` or
|
|
63
|
+
`adb shell am start -d <link>`.
|
|
64
|
+
|
|
65
|
+
## Several tasks at once (people and AI agents)
|
|
66
|
+
|
|
67
|
+
One debug build of the example can run any of several Metro servers, one per task or worktree. The
|
|
68
|
+
app needs `devPreviewServers: true` (the example has it).
|
|
69
|
+
|
|
70
|
+
1. In each worktree, start Metro with:
|
|
71
|
+
```sh
|
|
72
|
+
bun run start:preview # picks a free port in 8081-8099 and announces it
|
|
73
|
+
bun run start:preview -- -- --clear # after the second --, args go to expo start (bun eats the first)
|
|
74
|
+
```
|
|
75
|
+
In a terminal it asks for the name the app shows, prefilled from the branch; Enter keeps it.
|
|
76
|
+
`--title <name>` skips the question, and so does a run with no terminal.
|
|
77
|
+
A plain `npx expo start --port 8085` is found as well, with less detail (no branch).
|
|
78
|
+
2. Open the Previews tab in the app. "Dev preview servers" shows each server for this app within about two
|
|
79
|
+
seconds, with its branch, port and version. Switch runs that server; "Stop using dev preview server"
|
|
80
|
+
goes back.
|
|
81
|
+
3. Stop a server with Ctrl+C; it leaves the list on its own.
|
|
82
|
+
|
|
83
|
+
On the Android emulator nothing else is needed. A phone on USB needs `adb reverse` for each port;
|
|
84
|
+
`preview start` does it when `adb` is on the PATH. See [dev-preview-servers.md](./dev-preview-servers.md).
|
|
85
|
+
|
|
86
|
+
## Troubleshooting
|
|
87
|
+
|
|
88
|
+
- **"Expected JSON from … but got text/html"**: something other than the bucket answered. The URL is
|
|
89
|
+
not public, or a tunnel is showing its login page. Make the tunnel public, or use `localhost` with
|
|
90
|
+
`adb reverse`.
|
|
91
|
+
- **The list is empty**: nothing is published for this build's key. With the default
|
|
92
|
+
`compatibility: "appVersion"` the key is the app version, so publish again after a version bump.
|
|
93
|
+
With `"fingerprint"`, a prebuild or any native or app config change gives a new key, so publish
|
|
94
|
+
again after the build you are running.
|
|
95
|
+
- **Android cannot connect**: the `adb reverse` was lost when the emulator or phone restarted, or the
|
|
96
|
+
app was refused local network access (Android 17 asks). Run `adb reverse` again, or allow the
|
|
97
|
+
permission in the app's settings.
|
package/package.json
CHANGED
|
@@ -1,6 +1,109 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axonpack/preview",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Download and switch between preview JS bundles of an Expo app without a native rebuild",
|
|
5
|
+
"author": "Md Asadujjaman <abappi2019@gmail.com> (https://github.com/abappi19)",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"preview",
|
|
8
|
+
"ota",
|
|
9
|
+
"bundle",
|
|
10
|
+
"qa",
|
|
11
|
+
"expo",
|
|
12
|
+
"react-native"
|
|
13
|
+
],
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/axonpack/axonpack/issues"
|
|
16
|
+
},
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"homepage": "https://axonpack.dev/docs/preview/",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/axonpack/axonpack.git",
|
|
22
|
+
"directory": "packages/@axonpack/preview"
|
|
23
|
+
},
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"registry": "https://registry.npmjs.org/"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"android",
|
|
29
|
+
"ios",
|
|
30
|
+
"bin",
|
|
31
|
+
"build",
|
|
32
|
+
"app.plugin.js",
|
|
33
|
+
"expo-module.config.json",
|
|
34
|
+
"CHANGELOG.md",
|
|
35
|
+
"notes"
|
|
36
|
+
],
|
|
37
|
+
"main": "build/index.js",
|
|
38
|
+
"types": "build/index.d.ts",
|
|
39
|
+
"bin": {
|
|
40
|
+
"preview": "bin/preview.js"
|
|
41
|
+
},
|
|
42
|
+
"sideEffects": false,
|
|
43
|
+
"exports": {
|
|
44
|
+
".": {
|
|
45
|
+
"types": {
|
|
46
|
+
"expo-source": "./src/index.ts",
|
|
47
|
+
"default": "./build/index.d.ts"
|
|
48
|
+
},
|
|
49
|
+
"expo-source": "./src/index.ts",
|
|
50
|
+
"default": "./build/index.js"
|
|
51
|
+
},
|
|
52
|
+
"./app.plugin.js": "./app.plugin.js",
|
|
53
|
+
"./package.json": "./package.json"
|
|
54
|
+
},
|
|
55
|
+
"scripts": {
|
|
56
|
+
"build": "rm -rf build && tsc && bun build src/cli.ts --target=node --format=cjs --outfile=build/cli.cjs",
|
|
57
|
+
"prepare": "bun run build",
|
|
58
|
+
"clean": "rm -rf build",
|
|
59
|
+
"lint": "oxlint src",
|
|
60
|
+
"format": "oxlint src --fix",
|
|
61
|
+
"test": "jest",
|
|
62
|
+
"check-types": "tsc --noEmit -p tsconfig.check.json",
|
|
63
|
+
"storage:local": "./local-s3/run.sh start",
|
|
64
|
+
"storage:local:stop": "./local-s3/run.sh stop",
|
|
65
|
+
"storage:local:reset": "./local-s3/run.sh reset"
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@babel/runtime": "^7.28.4",
|
|
69
|
+
"@types/jest": "^29.2.1",
|
|
70
|
+
"@types/node": "^24.0.0",
|
|
71
|
+
"@types/react": "~19.3.0",
|
|
72
|
+
"@types/react-test-renderer": "^19.1.0",
|
|
73
|
+
"expo": "^57.0.7",
|
|
74
|
+
"expo-file-system": "~58.0.11",
|
|
75
|
+
"jest": "^29.7.0",
|
|
76
|
+
"jest-expo": "~57.0.2",
|
|
77
|
+
"linter": "*",
|
|
78
|
+
"oxlint": "^1.80.0",
|
|
79
|
+
"react": "19.3.0",
|
|
80
|
+
"react-native": "0.86.0",
|
|
81
|
+
"react-test-renderer": "19.3.0",
|
|
82
|
+
"typescript": "^5.9.2"
|
|
83
|
+
},
|
|
84
|
+
"peerDependencies": {
|
|
85
|
+
"expo": ">=53",
|
|
86
|
+
"react": ">=18",
|
|
87
|
+
"react-native": ">=0.79",
|
|
88
|
+
"expo-file-system": "*"
|
|
89
|
+
},
|
|
90
|
+
"jest": {
|
|
91
|
+
"preset": "jest-expo",
|
|
92
|
+
"roots": [
|
|
93
|
+
"<rootDir>/src"
|
|
94
|
+
],
|
|
95
|
+
"testMatch": [
|
|
96
|
+
"**/*.test.ts",
|
|
97
|
+
"**/*.test.tsx"
|
|
98
|
+
],
|
|
99
|
+
"transformIgnorePatterns": [
|
|
100
|
+
"node_modules/(?!.*(react-native|expo|@noble))"
|
|
101
|
+
],
|
|
102
|
+
"moduleNameMapper": {
|
|
103
|
+
"^@babel/runtime/(.*)$": "<rootDir>/node_modules/@babel/runtime/$1"
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
"dependencies": {
|
|
107
|
+
"@noble/hashes": "^2.4.0"
|
|
108
|
+
}
|
|
109
|
+
}
|