@arkeytyp/valu-api 1.1.2 → 1.1.3

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.
Files changed (3) hide show
  1. package/README.md +143 -55
  2. package/package.json +1 -1
  3. package/src/ValuApi.js +2 -2
package/README.md CHANGED
@@ -227,99 +227,187 @@ console.log(reply);
227
227
 
228
228
  # Routing in Valu iFrame Applications
229
229
 
230
- The application is embedded inside Valuverse and controlled by the host.
230
+ Valu Social allows third‑party developers to register **mini‑applications** that are rendered inside the platform using **iframes**.
231
231
 
232
- - Valuverse owns the global routing context
233
- - Your app receives route updates from Valu
234
- - Your app should push navigation changes back to Valu
232
+ Each mini‑app:
235
233
 
236
- ---
234
+ * Has a unique **application ID / slug**
235
+ * Is mounted under a dedicated URL namespace in Valu Social
236
+ * Can manage its own internal routing (for example using React Router)
237
+
238
+ The host application (Valu Social) and the iframe application must stay **route‑synchronized** to ensure:
237
239
 
238
- ## Important Concept: Route Visibility
240
+ * Correct deep‑linking
241
+ * Proper browser navigation (back / forward)
242
+ * Shareable URLs
239
243
 
240
- There are **two different routing scopes**:
244
+ ---
241
245
 
242
- ### Local (App-only) Routing
243
- Routing handled only inside your application (e.g. React Router).
246
+ ## Application Configuration
244
247
 
245
- - App works normally
246
- - ❌ Routes are **not visible** to Valuverse
247
- - ❌ No deep linking from the main application
248
+ A mini‑application is registered with a configuration similar to the following:
248
249
 
249
- ### Valu Routing (Host-aware)
250
- Routing handled through Valu API.
250
+ ```json
251
+ {
252
+ "id": "demo-app",
253
+ "slug": "demo-app",
254
+ "iframe": {
255
+ "url": "https://sample.texpo.io"
256
+ }
257
+ }
258
+ ```
251
259
 
252
- - ✅ Routes appear in the main application
253
- - ✅ Deep linking works
254
- - Navigation state is shared with Valuverse
260
+ Key fields:
261
+
262
+ * **id / slug** determines the public URL under valu-social.com
263
+ * **iframe.url** – the base URL loaded inside the iframe
255
264
 
256
265
  ---
257
266
 
258
- ## Using React Router in an iFrame App
267
+ ## Host Iframe Route Mapping
259
268
 
260
- Using **React Router inside an iFrame Valu app is totally fine**.
269
+ Valu Social automatically maps routes from the host URL to the iframe URL.
261
270
 
262
- Your application will:
263
- - render pages correctly
264
- - navigate normally
265
- - function as a self-contained UI
271
+ ### Base Route
266
272
 
267
- However:
273
+ When a user opens:
268
274
 
269
- - those routes are **internal only**
270
- - they **do not propagate** to Valuverse
271
- - the main application will not see or control them
275
+ ```
276
+ https://valu-social.com/demo-app
277
+ ```
272
278
 
273
- This approach is acceptable for:
274
- - demo applications
275
- - prototypes
276
- - isolated tools
277
- - apps that do not need host-level routing
279
+ Valu Social loads the iframe at:
280
+
281
+ ```
282
+ https://sample.texpo.io/
283
+ ```
278
284
 
279
285
  ---
280
286
 
281
- ## Best Practice for Valuverse Applications
287
+ ### Nested Routes
282
288
 
283
- If your application is built to behave like a **native Valuverse app**, the recommended approach is:
289
+ When a user opens:
284
290
 
285
- > **Use Valu routing instead of (or in addition to) local routing.**
291
+ ```
292
+ https://valu-social.com/demo-app/page/1
293
+ ```
286
294
 
287
- This ensures:
288
- - consistent navigation behavior
289
- - correct deep linking
290
- - visibility in the main application router
291
- - proper docking and context switching
295
+ Valu Social loads the iframe at:
296
+
297
+ ```
298
+ https://sample.texpo.io/page/1
299
+ ```
300
+
301
+ 📌 **Rule:**
302
+
303
+ ```
304
+ /valu-social/<app-slug>/<path>
305
+
306
+ <iframe-base-url>/<path>
307
+ ```
308
+
309
+ No additional configuration is required for this behavior.
292
310
 
293
311
  ---
294
312
 
295
- ## Valu Routing API
313
+ ## Iframe Host Route Synchronization
296
314
 
297
- ### Subscribing to Route Changes
315
+ If your mini‑application uses **client‑side routing** (for example React Router), route changes **inside the iframe** are not automatically reflected in the Valu Social URL.
298
316
 
299
- Valu notifies your application when the route changes:
317
+ To keep the host URL in sync, your app must explicitly report route changes using:
300
318
 
301
319
  ```ts
302
- valuApi.addEventListener(ValuApi.ON_ROUTE, (route) => {
303
- // route example:
304
- // "/console"
305
- // "/api/users/id/123"
306
- });
320
+ valuApi.pushRoute(pathname);
307
321
  ```
308
322
 
309
- ### Pushing a New Route
323
+ This ensures:
324
+
325
+ * The browser URL updates correctly
326
+ * Deep links work as expected
327
+ * Page refresh restores the correct internal state
310
328
 
311
- Navigate forward:
329
+ ---
330
+
331
+ ## React Router Integration (Recommended)
332
+
333
+ ### Valu Router Bridge Component
334
+
335
+ Below is a small helper component that listens for route changes and reports them to Valu Social.
312
336
 
313
337
  ```ts
314
- valuApi.pushRoute("/documentation");
338
+ import { useEffect } from "react";
339
+ import { useLocation } from "react-router-dom";
340
+ import { useValuAPI } from "@/Hooks/useValuApi";
341
+
342
+ export function ValuRouterBridge() {
343
+ const valuApi = useValuAPI();
344
+ const { pathname } = useLocation();
345
+
346
+ // Iframe → Host
347
+ useEffect(() => {
348
+ if (!valuApi) return;
349
+ valuApi.pushRoute(pathname);
350
+ }, [valuApi, pathname]);
351
+
352
+ return null;
353
+ }
315
354
  ```
316
355
 
317
- Replacing the Current Route
318
- Redirect without adding a history entry:
356
+ What this does:
319
357
 
320
- ```ts
321
- valuApi.replaceRoute("/console");
358
+ * Listens to internal route changes via `useLocation()`
359
+ * Pushes the current pathname to Valu Social
360
+ * Keeps host and iframe URLs aligned
361
+
362
+ ---
363
+
364
+ ## Example Application Setup
365
+
366
+ Below is an example of how the bridge is used inside a React application with React Router:
367
+
368
+ ```tsx
369
+ export default function Home() {
370
+ return (
371
+ <BrowserRouter>
372
+ <ValuRouterBridge />
373
+
374
+ <div className="flex flex-col min-h-screen">
375
+ <TopBar isIFrame={false} />
376
+
377
+ <main className="flex-grow w-full px-4 py-8">
378
+ <div className="max-w-[1400px] mx-auto">
379
+ <Routes>
380
+ <Route path="/" element={<Navigate to="/console" replace />} />
381
+
382
+ <Route
383
+ path="/console"
384
+ element={
385
+ <>
386
+ <Console />
387
+ <SampleApiCalls />
388
+ </>
389
+ }
390
+ />
391
+
392
+ <Route path="/storage" element={<ApplicationStorage />} />
393
+ <Route path="/documentation" element={<Documentation />} />
394
+ </Routes>
395
+ </div>
396
+ </main>
397
+
398
+ <Footer />
399
+ </div>
400
+ </BrowserRouter>
401
+ );
402
+ }
322
403
  ```
404
+ ---
405
+
406
+ ## Best Practices
407
+
408
+ * Always report route changes using `valuApi.pushRoute`
409
+ * Use relative paths (e.g. `/console`, `/page/1`)
410
+ * Ensure your app can handle being opened directly on any route
323
411
 
324
412
  ## Sample Project
325
413
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkeytyp/valu-api",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "A package for developing iframe applications for Valu Social. Allows invoking functions of registered Valu applications and subscribing to events, as well as other features that enable developers creating own ifram apps for the value social",
5
5
  "main": "src/ValuApi.js",
6
6
  "scripts": {
package/src/ValuApi.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {EventEmitter} from "./EventEmitter.js";
2
2
  import {APIPointer} from "./APIPointer.js";
3
3
  import {guid4, nextId} from "./Utils.js";
4
- import {Intent} from "./Intent";
4
+ import {Intent} from "./Intent.js";
5
5
 
6
6
  export { ValuApplication } from "./ValuApplication.js";
7
7
  export { Intent } from "./Intent.js";
@@ -311,4 +311,4 @@ export class ValuApi {
311
311
  }
312
312
  }
313
313
  }
314
- }
314
+ }