@despia/local 1.0.7 → 1.0.9

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
@@ -4,7 +4,7 @@ Universal build plugin to generate `despia/local.json` manifest for [Despia](htt
4
4
 
5
5
  **Note**: Despia's local server is optional. Normally, the Despia runtime can run your web app directly from a URL. Despia's local server is for developers who need extra performance and full true native offline support.
6
6
 
7
- **Store Compliant**: Despia's local server is fully compliant with Apple App Store and Google Play Store guidelines. It downloads and caches web content (HTML, CSS, JavaScript) for offline display in a WebViewidentical to how web browsers work. No native code or executables are downloaded. See [Store Compliance & Security](#store-compliance--security) section for detailed compliance information.
7
+ **Store Compliant**: Despia's local server is fully compliant with Apple App Store and Google Play Store guidelines. It downloads and caches web content (HTML, CSS, JavaScript) for offline display in a WebView - identical to how web browsers work. No native code or executables are downloaded. See [Store Compliance & Security](#store-compliance--security) section for detailed compliance information.
8
8
 
9
9
  ## Features
10
10
 
@@ -15,12 +15,33 @@ Universal build plugin to generate `despia/local.json` manifest for [Despia](htt
15
15
  - **Sorted Output** - Alphabetically sorted paths for consistent builds
16
16
  - **Standalone Script** - Can be used with any build system via CLI
17
17
 
18
+ ## Setup
19
+
20
+ > **No changes to your hosting.** Add this build plugin to your existing setup, deploy your web app, then enable the feature in Despia.
21
+
22
+ 1. Add the plugin to your build configuration (see [Framework Support](#framework-support)).
23
+ 2. Deploy your web app — the plugin generates `despia/local.json` alongside your existing build output.
24
+ 3. In Despia: **Open your project → Settings → Local Server → Enable**.
25
+
26
+ **Prerequisite:** The local server can only be enabled after the plugin is added and your web app has been fully deployed with the generated manifest. Until then, the option will not be available.
27
+
18
28
  ## About Despia's Local Server
19
29
 
20
30
  **Note**: Despia's local server is optional. Normally, the Despia runtime can run your web app directly from a URL. Despia's local server is for developers who need extra performance and full true native offline support.
21
31
 
22
32
  Despia's local server enables your web app to run entirely from a local HTTP server on-device, providing a native app experience with full offline functionality.
23
33
 
34
+ ### Ownership & Control
35
+
36
+ The local server provides an OTA-capable system with a **secure origin** (`http://localhost`) and **full web API access**. It supports local-first apps, offline-capable apps, and apps requiring improved performance. The deployment pipeline remains under your control:
37
+
38
+ - **No MAU fees** — No per-user or usage-based charges
39
+ - **No proprietary OTA hosting** — Deploy assets to any host (CDN, Vercel, Netlify, or your own infrastructure)
40
+ - **Fully client-side** — The update logic runs entirely on the client; no dedicated OTA backend required
41
+ - **Pipeline control** — Integrate with your existing build and deployment workflow
42
+
43
+ Updates do not depend on third-party OTA infrastructure. The system runs entirely client-side, providing high reliability with update latency comparable to cloud-based solutions. Local assets are served from the local assets stored on the native file system; network requests occur only when a new deployment is detected.
44
+
24
45
  ### Architecture
25
46
 
26
47
  The Despia native container consists of:
@@ -80,6 +101,21 @@ When connectivity is available, Despia checks for updates in the background and
80
101
 
81
102
  **Important**: Updates only change web content (HTML, CSS, JavaScript). Native code, permissions, and app functionality remain unchanged from the original App Store/Play Store submission.
82
103
 
104
+ ### Smart OTA Cache System
105
+
106
+ > **Role of `deployed_at` in conditional update logic**
107
+
108
+ On startup, the client fetches `despia/local.json` and compares `deployed_at` with the cached value to determine whether a full asset download is required:
109
+
110
+ | Scenario | Behavior |
111
+ |----------|----------|
112
+ | **Good connection** | Fetch manifest and compare `deployed_at` to cached value |
113
+ | **`deployed_at` changed** | New deployment detected → download all assets → set as active app source |
114
+ | **`deployed_at` unchanged** | Serve from existing local cache; no download |
115
+ | **Poor or no connection** | Serve from offline cache; defer manifest check until connectivity improves |
116
+
117
+ This approach minimizes network requests while preserving OTA update capability. The `deployed_at` field acts as a lightweight change indicator; a full asset download is performed only when it has changed.
118
+
83
119
  ### Store Compliance & Security
84
120
 
85
121
  **Compliance Summary for App Reviewers:**
@@ -155,7 +191,7 @@ Despia's local server complies with this guideline because:
155
191
  - Binary behavior
156
192
  - System integration
157
193
 
158
- **However**, the web UI can be updated to use existing native APIs in new ways. For example, if Face ID is already implemented in the native code and exposed through the WebView bridge, the web UI can be updated to call Face ID from new parts of the app. This is compliant because the native capability already exists in the submitted binaryonly the web UI's usage of it changes.
194
+ **However**, the web UI can be updated to use existing native APIs in new ways. For example, if Face ID is already implemented in the native code and exposed through the WebView bridge, the web UI can be updated to call Face ID from new parts of the app. This is compliant because the native capability already exists in the submitted binary - only the web UI's usage of it changes.
159
195
 
160
196
  **Note**: This follows the same pattern as [Expo](https://expo.dev), which has been generally accepted by app stores. However, Apple's interpretation of "feature changes" under Guideline 3.3.2 is subjective, and your app could still face review challenges. It's recommended to be conservative with updates that significantly change app behavior, even when using existing native APIs.
161
197
 
@@ -183,7 +219,7 @@ Despia's local server complies with this policy because:
183
219
 
184
220
  4. **Sandboxed Execution**: All web content executes within the WebView's security sandbox, with permissions and capabilities fixed at APK submission time.
185
221
 
186
- **However**, the web UI can be updated to use existing native APIs in new ways. For example, if biometric authentication is already implemented in the native code and exposed through the WebView bridge, the web UI can be updated to call it from new parts of the app. This is compliant because the native capability already exists in the submitted APKonly the web UI's usage of it changes.
222
+ **However**, the web UI can be updated to use existing native APIs in new ways. For example, if biometric authentication is already implemented in the native code and exposed through the WebView bridge, the web UI can be updated to call it from new parts of the app. This is compliant because the native capability already exists in the submitted APK - only the web UI's usage of it changes.
187
223
 
188
224
  **This approach is explicitly permitted** under Play Store policies, as evidenced by:
189
225
  - Chrome and other browsers rendering web content
@@ -648,6 +684,7 @@ The generated `despia/local.json` file contains an object with the entry HTML pa
648
684
  ```json
649
685
  {
650
686
  "entry": "/index.html",
687
+ "deployed_at": "1737225600000",
651
688
  "assets": [
652
689
  "/index.html",
653
690
  "/assets/app.abc123.css",
@@ -658,6 +695,7 @@ The generated `despia/local.json` file contains an object with the entry HTML pa
658
695
  ```
659
696
 
660
697
  - **`entry`**: The entry HTML file path (e.g., `/index.html`). **Required** - Local apps always need an entry point for client-side rendering. The entry path is also included in the `assets` array (unless `skipEntryHtml` is enabled).
698
+ - **`deployed_at`**: Timestamp in milliseconds (as string) when the manifest was generated. Updated on every deployment.
661
699
  - **`assets`**: A sorted array of all asset paths, **including the entry file**. When `skipEntryHtml` is enabled, the entry is still required in the manifest but won't be included in the `assets` array.
662
700
 
663
701
  ## Examples
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@despia/local",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Universal build plugin to generate despia/local.json manifest for offline caching in Despia web-native apps. Supports Vite, Webpack, Rollup, Nuxt, SvelteKit, Astro, Remix, esbuild, Parcel, and more.",
5
5
  "type": "module",
6
6
  "main": "./src/core.js",
package/src/core.js CHANGED
@@ -95,6 +95,7 @@ export function generateManifest({ outputDir, entryHtml = 'index.html', addition
95
95
  // Create manifest object (entry is always required for local client-side apps)
96
96
  const manifest = {
97
97
  entry: entryPath,
98
+ deployed_at: String(Date.now()),
98
99
  assets: assets
99
100
  };
100
101
 
package/src/webpack.js CHANGED
@@ -110,6 +110,7 @@ class DespiaLocalPlugin {
110
110
 
111
111
  const manifestObj = {
112
112
  entry: entryPath,
113
+ deployed_at: String(Date.now()),
113
114
  assets: assetList
114
115
  };
115
116
  const manifest = JSON.stringify(manifestObj, null, 2);