flet-box 1.0.3 → 1.0.5

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 (172) hide show
  1. package/README.md +10 -0
  2. package/bin/cli.js +15 -0
  3. package/bin/commands/checkApi.js +761 -0
  4. package/bin/commands/create.js +77 -5
  5. package/bin/utils/dtsProps.js +191 -0
  6. package/bin/utils/moduleExports.js +165 -0
  7. package/bin/utils/neutralise.js +64 -0
  8. package/bin/utils/templates.js +366 -27
  9. package/docs/CONTRIBUTING.md +156 -0
  10. package/docs/README.md +68 -0
  11. package/docs/arquitectura.md +164 -0
  12. package/docs/cli/README.md +542 -0
  13. package/docs/guides/README.md +33 -0
  14. package/docs/guides/app-templates.md +197 -0
  15. package/docs/guides/compatibility.md +95 -0
  16. package/docs/guides/embedding.md +284 -0
  17. package/docs/guides/first-app.md +208 -0
  18. package/docs/guides/frontend-services.md +171 -0
  19. package/docs/guides/minification-and-protection.md +260 -0
  20. package/docs/guides/mobile-and-platforms.md +439 -0
  21. package/docs/guides/online-updates.md +196 -0
  22. package/docs/guides/router.md +282 -0
  23. package/docs/guides/state.md +283 -0
  24. package/docs/guides/syntax-philosophy.md +150 -0
  25. package/docs/guides/utilities.md +241 -0
  26. package/docs/guides/widget-structure.md +163 -0
  27. package/docs/server/README.md +68 -0
  28. package/docs/server/START_HERE.md +121 -0
  29. package/docs/server/api.md +225 -0
  30. package/docs/server/data-services.md +300 -0
  31. package/docs/server/deployment.md +113 -0
  32. package/docs/server/security.md +196 -0
  33. package/docs/services/README.md +79 -0
  34. package/docs/services/RamStore.md +84 -0
  35. package/docs/services/Session.md +84 -0
  36. package/docs/services/Storage.md +88 -0
  37. package/docs/services/http.md +86 -0
  38. package/docs/tools/README.md +138 -0
  39. package/docs/tools/animation.md +87 -0
  40. package/docs/tools/async-ids-log.md +80 -0
  41. package/docs/tools/device.md +132 -0
  42. package/docs/tools/introspection.md +67 -0
  43. package/docs/tools/lists.md +96 -0
  44. package/docs/tools/markdown.md +79 -0
  45. package/docs/tools/reactivity.md +288 -0
  46. package/docs/tools/state.md +103 -0
  47. package/docs/tools/styling.md +92 -0
  48. package/docs/tools/text-and-time.md +89 -0
  49. package/docs/tools/theme.md +102 -0
  50. package/docs/tools/validation.md +75 -0
  51. package/docs/tools/visual-effects.md +84 -0
  52. package/docs/widget/Accordion.md +144 -0
  53. package/docs/widget/AdMob.md +144 -0
  54. package/docs/widget/AdSense.md +133 -0
  55. package/docs/widget/AdaptiveScaffold.md +105 -0
  56. package/docs/widget/AlertDialog.md +103 -0
  57. package/docs/widget/AnimatedBox.md +130 -0
  58. package/docs/widget/AnimatedText.md +123 -0
  59. package/docs/widget/AppBar.md +118 -0
  60. package/docs/widget/Audio.md +135 -0
  61. package/docs/widget/Avatar.md +119 -0
  62. package/docs/widget/Badge.md +128 -0
  63. package/docs/widget/BottomNavigation.md +116 -0
  64. package/docs/widget/BottomSheet.md +125 -0
  65. package/docs/widget/Button.md +137 -0
  66. package/docs/widget/COMMON_PROPS.md +150 -0
  67. package/docs/widget/Card.md +125 -0
  68. package/docs/widget/Carousel.md +151 -0
  69. package/docs/widget/Chart.md +151 -0
  70. package/docs/widget/Checkbox.md +118 -0
  71. package/docs/widget/Chip.md +126 -0
  72. package/docs/widget/CircularBar.md +168 -0
  73. package/docs/widget/CircularChart.md +164 -0
  74. package/docs/widget/CodeViewer.md +130 -0
  75. package/docs/widget/CollapsibleSideBar.md +112 -0
  76. package/docs/widget/Column.md +129 -0
  77. package/docs/widget/Container.md +136 -0
  78. package/docs/widget/DataTable.md +150 -0
  79. package/docs/widget/Divider.md +109 -0
  80. package/docs/widget/DraggBox.md +129 -0
  81. package/docs/widget/Drawer.md +135 -0
  82. package/docs/widget/DrawerItem.md +98 -0
  83. package/docs/widget/Dropdown.md +139 -0
  84. package/docs/widget/DroppBox.md +152 -0
  85. package/docs/widget/FloatingActionButton.md +120 -0
  86. package/docs/widget/GridView.md +140 -0
  87. package/docs/widget/Icon.md +117 -0
  88. package/docs/widget/Image.md +125 -0
  89. package/docs/widget/Input.md +151 -0
  90. package/docs/widget/Inspector.md +92 -0
  91. package/docs/widget/InstallButton.md +128 -0
  92. package/docs/widget/ListTile.md +132 -0
  93. package/docs/widget/ListView.md +138 -0
  94. package/docs/widget/Markdown.md +175 -0
  95. package/docs/widget/MatrixRain.md +122 -0
  96. package/docs/widget/Modal.md +129 -0
  97. package/docs/widget/Pagination.md +135 -0
  98. package/docs/widget/ParallaxBox.md +128 -0
  99. package/docs/widget/ProgressBar.md +130 -0
  100. package/docs/widget/QRCode.md +117 -0
  101. package/docs/widget/README.md +188 -0
  102. package/docs/widget/Radio.md +123 -0
  103. package/docs/widget/Rating.md +131 -0
  104. package/docs/widget/Row.md +131 -0
  105. package/docs/widget/START_HERE.md +146 -0
  106. package/docs/widget/Scaffold.md +152 -0
  107. package/docs/widget/Skeleton.md +130 -0
  108. package/docs/widget/Slider.md +146 -0
  109. package/docs/widget/SnackBar.md +102 -0
  110. package/docs/widget/Stack.md +128 -0
  111. package/docs/widget/Stepper.md +145 -0
  112. package/docs/widget/Switch.md +118 -0
  113. package/docs/widget/Tabs.md +124 -0
  114. package/docs/widget/Text.md +133 -0
  115. package/docs/widget/Tooltip.md +145 -0
  116. package/docs/widget/TreeView.md +176 -0
  117. package/docs/widget/Video.md +127 -0
  118. package/docs/widget/_template.md +61 -0
  119. package/package.json +4 -2
  120. package/src/animations/AnimatedBox.js +32 -1
  121. package/src/animations/AnimatedText.js +7 -3
  122. package/src/animations/MatrixRain.js +37 -12
  123. package/src/animations/ParallaxBox.js +16 -3
  124. package/src/animations/animate.js +187 -58
  125. package/src/animations/index.js +1 -0
  126. package/src/core/runApp.js +13 -1
  127. package/src/create-index.sh +1 -1
  128. package/src/index.d.ts +227 -91
  129. package/src/index.js +1 -0
  130. package/src/navigations/AdaptiveScaffold.js +11 -2
  131. package/src/navigations/AppBar.js +8 -2
  132. package/src/navigations/BottomNavigation.js +24 -5
  133. package/src/navigations/DrawerItem.js +16 -3
  134. package/src/navigations/Scaffold.js +8 -1
  135. package/src/navigations/Tabs.js +40 -8
  136. package/src/tools/dimensions.js +11 -3
  137. package/src/tools/useState.js +139 -101
  138. package/src/utils/getWidgetProps.js +5 -3
  139. package/src/widget-factory/assignProps.js +30 -11
  140. package/src/widget-factory/processProps.js +17 -5
  141. package/src/widget-factory/reactiveValue.js +172 -0
  142. package/src/widget-factory/translateProps.js +777 -901
  143. package/src/widget-factory/warnings.js +15 -0
  144. package/src/widget-factory/widgetFactory.js +27 -0
  145. package/src/widgets/Accordion.js +6 -5
  146. package/src/widgets/AlertDialog.js +7 -5
  147. package/src/widgets/Audio.js +30 -8
  148. package/src/widgets/BottomSheet.js +24 -1
  149. package/src/widgets/Chart.js +4 -1
  150. package/src/widgets/Checkbox.js +16 -8
  151. package/src/widgets/CircularBar.js +12 -1
  152. package/src/widgets/CircularChart.js +4 -1
  153. package/src/widgets/CodeViewer.js +26 -8
  154. package/src/widgets/DataTable.js +11 -2
  155. package/src/widgets/Dropdown.js +5 -1
  156. package/src/widgets/FloatingActionButton.js +4 -7
  157. package/src/widgets/Image.js +7 -2
  158. package/src/widgets/Input.js +119 -6
  159. package/src/widgets/Inspector.js +16 -10
  160. package/src/widgets/ListView.js +80 -30
  161. package/src/widgets/Markdown.js +53 -8
  162. package/src/widgets/Modal.js +24 -1
  163. package/src/widgets/Pagination.js +6 -3
  164. package/src/widgets/ProgressBar.js +16 -13
  165. package/src/widgets/QRCode.js +9 -2
  166. package/src/widgets/Radio.js +11 -8
  167. package/src/widgets/Slider.js +26 -4
  168. package/src/widgets/SnackBar.js +20 -2
  169. package/src/widgets/Stack.js +36 -3
  170. package/src/widgets/Stepper.js +4 -3
  171. package/src/widgets/Switch.js +8 -5
  172. package/src/widgets/TreeView.js +3 -2
@@ -0,0 +1,196 @@
1
+ # Authentication and security
2
+
3
+ ## Start securely
4
+
5
+ Use `runSecureServer()` as the default starting point for a real API:
6
+
7
+ ```javascript
8
+ import { Api, runSecureServer } from "flet-box-server";
9
+
10
+ const routes = Api({
11
+ "/health": { GET: () => ({ ok: true }) },
12
+ });
13
+
14
+ runSecureServer(routes, {
15
+ port: 3000,
16
+ docs: true,
17
+ rateLimit: { max: 100, windowMs: 60_000 },
18
+ });
19
+ ```
20
+
21
+ This enables security middleware, input cleaning, validation, malicious-content blocking, and rate limiting according to the server options.
22
+
23
+ ## JWT login
24
+
25
+ The security database supports a password grant through a token handler. A development login request looks like this:
26
+
27
+ ```javascript
28
+ const response = await fetch("http://localhost:3000/login", {
29
+ method: "POST",
30
+ headers: { "Content-Type": "application/json" },
31
+ body: JSON.stringify({
32
+ grant_type: "password",
33
+ username: process.env.ADMIN_USERNAME,
34
+ password: process.env.ADMIN_PASSWORD,
35
+ }),
36
+ });
37
+
38
+ const { access_token } = await response.json();
39
+ ```
40
+
41
+ Send the token with protected requests:
42
+
43
+ ```javascript
44
+ fetch("http://localhost:3000/private", {
45
+ headers: {
46
+ Authorization: `Bearer ${access_token}`,
47
+ },
48
+ });
49
+ ```
50
+
51
+ ## Protect a route
52
+
53
+ ```javascript
54
+ import { authenticate } from "flet-box-server";
55
+
56
+ const routes = Api({
57
+ "/private": {
58
+ GET: {
59
+ handler: ({ req }) => ({
60
+ user: req.user,
61
+ secret: "private data",
62
+ }),
63
+ middleware: [authenticate],
64
+ },
65
+ },
66
+ });
67
+ ```
68
+
69
+ `authenticate` rejects missing or invalid bearer tokens with status `401` and adds the verified payload to `req.user`.
70
+
71
+ ## Roles
72
+
73
+ Use `hasRole()` after authentication:
74
+
75
+ ```javascript
76
+ import { authenticate, hasRole } from "flet-box-server";
77
+
78
+ const routes = Api({
79
+ "/admin": {
80
+ GET: {
81
+ handler: () => ({ area: "admin" }),
82
+ middleware: [authenticate, hasRole("admin")],
83
+ },
84
+ },
85
+ });
86
+ ```
87
+
88
+ A user must be authenticated before roles can be checked.
89
+
90
+ ## Optional authentication
91
+
92
+ Use `optionalAuth` when a route works for visitors but can provide extra data to logged-in users:
93
+
94
+ ```javascript
95
+ import { optionalAuth } from "flet-box-server";
96
+
97
+ middleware: [optionalAuth]
98
+ ```
99
+
100
+ ## Input sanitization
101
+
102
+ `securityCheck` can:
103
+
104
+ - Check blocked IPs, paths, and user agents.
105
+ - Sanitize request body, query, and path parameters.
106
+ - Apply security headers.
107
+ - Apply CORS rules.
108
+
109
+ Do not treat sanitization as a replacement for validation. Validate the expected type and business rules too.
110
+
111
+ ## Malicious-content blocking
112
+
113
+ `blockMalicious` checks body, params, and query values against known suspicious patterns and returns `403` when a pattern is detected.
114
+
115
+ Use it as route middleware when appropriate:
116
+
117
+ ```javascript
118
+ middleware: [authenticate, blockMalicious, securityCheck]
119
+ ```
120
+
121
+ False positives are possible. Review the accepted input for your application instead of blindly allowing all content.
122
+
123
+ ## Schema validation
124
+
125
+ Use `SchemaValidator` for explicit validation:
126
+
127
+ ```javascript
128
+ import { SchemaValidator } from "flet-box-server";
129
+
130
+ const validator = new SchemaValidator({
131
+ name: { type: "string", required: true, minLength: 2 },
132
+ age: { type: "number", min: 0 },
133
+ email: { type: "email", required: true },
134
+ });
135
+
136
+ const result = validator.validate({
137
+ name: "Ada",
138
+ age: 36,
139
+ email: "ada@example.com",
140
+ });
141
+
142
+ if (!result.valid) {
143
+ console.log(result.errors);
144
+ }
145
+ ```
146
+
147
+ Supported validation concepts include strings, numbers, booleans, email, URL, date, UUID, arrays, objects, required fields, ranges, lengths, enums, defaults, and custom patterns.
148
+
149
+ ## Rate limiting
150
+
151
+ Create a route limiter:
152
+
153
+ ```javascript
154
+ import { rateLimit } from "flet-box-server";
155
+
156
+ const limiter = rateLimit({
157
+ max: 10,
158
+ windowMs: 60_000,
159
+ message: "Too many requests",
160
+ });
161
+
162
+ const routes = Api({
163
+ "/login": {
164
+ POST: {
165
+ handler: login,
166
+ middleware: [limiter],
167
+ },
168
+ },
169
+ });
170
+ ```
171
+
172
+ For multiple server instances, use a shared store such as Redis rather than only an in-memory map.
173
+
174
+ ## Security headers and CORS
175
+
176
+ `securityCheck` applies headers such as content-type protection, frame protection, referrer policy, and content security policy.
177
+
178
+ CORS origins can be configured with the environment variable:
179
+
180
+ ```bash
181
+ CORS_ORIGINS=https://my-app.example.com,https://admin.example.com
182
+ ```
183
+
184
+ Avoid `*` with credentials in production. Use an explicit allowlist.
185
+
186
+ ## Production checklist
187
+
188
+ - Set a long random `JWT_SECRET`.
189
+ - Remove hardcoded admin users and passwords.
190
+ - Never commit SMTP, Twilio, Redis, or cloud credentials.
191
+ - Use HTTPS.
192
+ - Restrict CORS origins.
193
+ - Enable validation and rate limiting.
194
+ - Review sanitization false positives.
195
+ - Store verification codes and sessions in a shared store when scaling.
196
+ - Log security events without logging passwords or tokens.
@@ -0,0 +1,79 @@
1
+ # Services: FletBox data & network helpers
2
+
3
+ This directory is the reference index for the services that ship with FletBox — the helpers that connect your app to the **outside world**: browser storage and the network.
4
+
5
+ Services are plain JavaScript functions and objects. You import them from `flet-box`:
6
+
7
+ ```javascript
8
+ import { saveData, getData, httpGet, subscribeRam } from "flet-box";
9
+ ```
10
+
11
+ > **Services vs. Tools.** *Services* talk to the outside world (storage, network) and may be async or stateful. *Tools* are pure helpers that turn input into a value. Find tools in the [tools index](../tools/README.md).
12
+
13
+ For a task-oriented walkthrough of the three storage layers, read the [Frontend services guide](../guides/frontend-services.md). This index lists everything the framework actually exports today, grouped by layer, and **links to a full reference page for each layer** (every function with its signature and return value). The implementation lives in `src/services/` and every name below is present in `src/index.js`.
14
+
15
+ ## The four layers
16
+
17
+ | Page | Layer | Lifetime |
18
+ | --- | --- | --- |
19
+ | [RamStore](RamStore.md) | In-memory reactive state (backs `useState`) | While the page runs |
20
+ | [Session](Session.md) | `sessionStorage` | The tab session |
21
+ | [Storage](Storage.md) | `localStorage` | Until cleared |
22
+ | [HTTP client](http.md) | `fetch`-based network calls | Per request |
23
+
24
+ ## RamStore — in-memory reactive state
25
+
26
+ RAM storage, alive while the page runs. Backs `useState`'s keys.
27
+
28
+ - `RamStore` — class/instance access.
29
+ - `saveRam(key, value)`, `getRam(key)`, `getAllRam()`, `getAllRamKeys()`, `hasRam(key)`, `updateRam(key, value)`, `deleteRam(key)`, `clearAllRam()`, `getRamItemCount()`, `isRamAvailable()`.
30
+ - `subscribeRam(callback)` — subscribe to any RAM change; returns an unsubscribe function.
31
+
32
+ > Full detail, examples, and notes → [RamStore reference](RamStore.md).
33
+
34
+ ## Session — tab-scoped storage
35
+
36
+ Backed by `sessionStorage`: lives for the tab session, lost when the tab closes.
37
+
38
+ - `Session` — class/instance access.
39
+ - `saveSession(key, value)` (async), `getSession(key)` (async), `getSessionSync(key)`, `updateSession(key, value)`, `deleteSession(key)`, `clearAllSession()`, `hasSession(key)`, `getAllSessionKeys()`, `getAllSessionData()`, `getSessionSize()`, `deleteSessionByPrefix(prefix)`, `deleteSessionBySuffix(suffix)`, `getSessionItemCount()`, `isSessionAvailable()`.
40
+
41
+ > Full detail, examples, and notes → [Session reference](Session.md).
42
+
43
+ ## Storage — persistent data
44
+
45
+ Backed by `localStorage`: survives browser restarts until cleared.
46
+
47
+ - `Storage` — class/instance access.
48
+ - `saveData(key, value)` (async), `getData(key)` (async), `getDataSync(key)`, `updateData(key, value)`, `deleteData(key)`, `clearAllData()`, `hasData(key)`, `getAllKeys()`, `getAllData()`, `getStorageSize()`, `deleteDataByPrefix(prefix)`, `deleteDataBySuffix(suffix)`, `getItemCount()`, `isStorageAvailable()`.
49
+
50
+ > Full detail, examples, and notes → [Storage reference](Storage.md).
51
+
52
+ ## HTTP client
53
+
54
+ A small `fetch`-based client.
55
+
56
+ - `httpGet(url, options)`, `httpPost(url, options)`, `httpPut(url, options)`, `httpPatch(url, options)`, `httpDelete(url, options)` — all take a single options object with `body`, `params`, `headers`, and `timeout`.
57
+ - `httpRequest(method, url, options)` — generic request; see `HttpRequestOptions` in `src/index.d.ts`.
58
+
59
+ > Full detail, examples, and notes → [HTTP reference](http.md).
60
+
61
+ > **Security.** Never store passwords, private keys, or security secrets in any of these services. Browser storage is readable by anyone with access to the device, and any token in frontend code is visible to the user. Protect sensitive data with server-side authorization.
62
+
63
+ ## Where to go next
64
+
65
+ - [Frontend services guide](../guides/frontend-services.md) — the practical walkthrough for storage and HTTP.
66
+ - [Guides index](../guides/README.md) — every FletBox guide in reading order.
67
+ - [State guide](../guides/state.md) — `useState` and RAM-backed reactivity.
68
+ - [Tools index](../tools/README.md) — the pure helper functions.
69
+ - [Widgets](../widget/README.md) — the widget book.
70
+
71
+ ---
72
+
73
+ ## Continue reading
74
+
75
+ - **Previous:** [Frontend services guide](../guides/frontend-services.md)
76
+ - **Next:** [RamStore](RamStore.md)
77
+ - **Index:** [Guides index](../guides/README.md) · [The FletBox Book](../README.md)
78
+
79
+ You are reading **Chapter 9 · State, Router & Services** (chapter opener).
@@ -0,0 +1,84 @@
1
+ # RamStore
2
+
3
+ ## Overview
4
+ `RamStore` is the **in-memory** reactive store. It keeps data in a JavaScript `Map` while the page is open, notifies subscribers when any key changes, and powers `useState` under the hood. Everything is lost when the page reloads — that is its job.
5
+
6
+ ## When to use
7
+ - Share live values between widgets (the state engine behind `useState`).
8
+ - Keep temporary UI data — form steps, current filters, draft objects — that must disappear on reload.
9
+
10
+ ## Import
11
+
12
+ ```javascript
13
+ import { saveRam, getRam, subscribeRam, RamStore } from "flet-box";
14
+ ```
15
+
16
+ Every function also exists as a method of the exported `RamStore` object, for an object-style API.
17
+
18
+ ## Functions
19
+
20
+ | Function | Signature | Returns | Description |
21
+ | --- | --- | --- | --- |
22
+ | `saveRam` | `saveRam(key, value)` | `boolean` | Store or replace `value` under `key` and notify subscribers. |
23
+ | `getRam` | `getRam(key)` | `T \| null` | Read the value, or `null` if the key does not exist. |
24
+ | `getAllRam` | `getAllRam()` | `Record<string, any>` | Every stored key/value pair. |
25
+ | `getAllRamKeys` | `getAllRamKeys()` | `string[]` | All stored keys. |
26
+ | `hasRam` | `hasRam(key)` | `boolean` | Is the key present? |
27
+ | `updateRam` | `updateRam(key, value)` | `boolean` | Replace the value (same as `saveRam`). |
28
+ | `deleteRam` | `deleteRam(key)` | `boolean` | Remove a key. |
29
+ | `clearAllRam` | `clearAllRam()` | `boolean` | Remove everything. |
30
+ | `subscribeRam` | `subscribeRam(callback)` | `() => void` | Subscribe to changes, returns an unsubscribe function. |
31
+ | `getRamItemCount` | `getRamItemCount()` | `number` | How many keys are stored. |
32
+ | `isRamAvailable` | `isRamAvailable()` | `boolean` | Always `true` in a browser; kept for API symmetry with the other stores. |
33
+
34
+ The subscribe callback receives `(key, newValue, oldValue)`. Use your stored key as the first argument to filter.
35
+
36
+ ## Examples
37
+
38
+ ### Everyday example
39
+
40
+ ```javascript
41
+ import { saveRam, getRam } from "flet-box";
42
+
43
+ saveRam("cart", [{ id: 1 }, { id: 2 }]);
44
+ const cart = getRam("cart");
45
+ ```
46
+
47
+ ### Full example
48
+
49
+ ```javascript
50
+ import { saveRam, subscribeRam, deleteRam } from "flet-box";
51
+
52
+ const unsubscribe = subscribeRam((key, newValue, oldValue) => {
53
+ console.log(`${key}: ${oldValue} → ${newValue}`);
54
+ });
55
+
56
+ saveRam("theme", "dark"); // logs: theme: null → dark
57
+ deleteRam("theme"); // logs: theme: dark → null
58
+
59
+ // stop listening:
60
+ unsubscribe();
61
+ ```
62
+
63
+ ## Notes
64
+
65
+ - This is the store behind `useState`. When you call `setCount(...)`, FletBox saves through `RamStore` and re-renders registered widgets.
66
+ - Values can be any JSON-safe data: strings, numbers, booleans, arrays, objects.
67
+ - There is no expiration and no persistence. For data that survives a reload, use [Storage](Storage.md).
68
+ - Synchronous and dependency-free: subscribe handlers run in order and errors in one handler never break the others.
69
+
70
+ ## Related pages
71
+ - [Session](Session.md) — tab-scoped persistence.
72
+ - [Storage](Storage.md) — persistent storage.
73
+ - [Frontend services guide](../guides/frontend-services.md) — choosing a storage layer.
74
+ - [State guide](../guides/state.md) — `useState` and reactivity.
75
+
76
+ ---
77
+
78
+ ## Continue reading
79
+
80
+ - **Previous:** [Services index](README.md)
81
+ - **Next:** [Session](Session.md)
82
+ - **Index:** [Services index](README.md) · [The FletBox Book](../README.md)
83
+
84
+ You are reading **Chapter 9 · State, Router & Services** (1 of 4).
@@ -0,0 +1,84 @@
1
+ # Session
2
+
3
+ ## Overview
4
+ `Session` is the **tab-scoped** store, backed by `sessionStorage`. Data lives while the tab is open and disappears when the tab or the browser closes. It works with strings, numbers, booleans, arrays, and objects.
5
+
6
+ ## When to use
7
+ - Remember something for "this visit only": a cart while the user is on the page, a wizard step, a temporary token (see the security note).
8
+ - Keep data between multiple widgets that must not survive a full page reload more than once.
9
+
10
+ ## Import
11
+
12
+ ```javascript
13
+ import { saveSession, getSession, Session } from "flet-box";
14
+ ```
15
+
16
+ Every function also exists as a method of the exported `Session` object. The API mirrors [RamStore](RamStore.md) and [Storage](Storage.md) so you can swap the layer without rewriting your calls.
17
+
18
+ ## Functions
19
+
20
+ | Function | Signature | Returns | Description |
21
+ | --- | --- | --- | --- |
22
+ | `saveSession` | `saveSession(key, value)` | `boolean` | Store `value` under `key` in `sessionStorage`. |
23
+ | `getSession` | `getSession(key)` | `T \| null` | Read the value (async-safe wrapper). |
24
+ | `getSessionSync` | `getSessionSync(key)` | `T \| null` | Read the value synchronously. |
25
+ | `updateSession` | `updateSession(key, value)` | `boolean` | Replace the value. |
26
+ | `deleteSession` | `deleteSession(key)` | `boolean` | Remove one key. |
27
+ | `clearAllSession` | `clearAllSession()` | `boolean` | Remove every key for this tab session. |
28
+ | `hasSession` | `hasSession(key)` | `boolean` | Is the key present? |
29
+ | `getAllSessionKeys` | `getAllSessionKeys()` | `string[]` | All stored keys. |
30
+ | `getAllSessionData` | `getAllSessionData()` | `Record<string, any>` | Every key/value pair. |
31
+ | `getSessionSize` | `getSessionSize()` | `number` | Approximate size in bytes. |
32
+ | `deleteSessionByPrefix` | `deleteSessionByPrefix(prefix)` | `number` | Delete every key starting with `prefix`; returns the count. |
33
+ | `deleteSessionBySuffix` | `deleteSessionBySuffix(suffix)` | `number` | Delete every key ending with `suffix`; returns the count. |
34
+ | `getSessionItemCount` | `getSessionItemCount()` | `number` | How many keys are stored. |
35
+ | `isSessionAvailable` | `isSessionAvailable()` | `boolean` | Is `sessionStorage` available? |
36
+
37
+ ## Examples
38
+
39
+ ### Everyday example
40
+
41
+ ```javascript
42
+ import { saveSession, getSession } from "flet-box";
43
+
44
+ saveSession("wizard-step", 3);
45
+ const step = getSession("wizard-step");
46
+ ```
47
+
48
+ ### Full example
49
+
50
+ ```javascript
51
+ import { saveSession, getSessionSync, deleteSessionByPrefix } from "flet-box";
52
+
53
+ saveSession("form.name", "Ada");
54
+ saveSession("form.age", 36);
55
+ saveSession("draft-note", "hello");
56
+
57
+ getSessionSync("form.name"); // "Ada"
58
+
59
+ // remove all dashboard form keys at once:
60
+ const removed = deleteSessionByPrefix("form.");
61
+ console.log(removed); // 2
62
+ ```
63
+
64
+ ## Notes
65
+
66
+ - `sessionStorage` survives a *refresh* (F5) but not a new tab or a closed browser.
67
+ - Objects and arrays are serialized (and restored) as JSON automatically.
68
+ - Use `getSessionSync` inside hot paths where you cannot wait for a promise.
69
+ - **Security.** Never store passwords, private keys, or security tokens in browser storage — it is readable by anyone with access to the device. Protect sensitive data with server-side authorization.
70
+
71
+ ## Related pages
72
+ - [RamStore](RamStore.md) — the in-memory reactive store.
73
+ - [Storage](Storage.md) — persistent storage.
74
+ - [Frontend services guide](../guides/frontend-services.md) — choosing a storage layer.
75
+
76
+ ---
77
+
78
+ ## Continue reading
79
+
80
+ - **Previous:** [RamStore](RamStore.md)
81
+ - **Next:** [Storage](Storage.md)
82
+ - **Index:** [Services index](README.md) · [The FletBox Book](../README.md)
83
+
84
+ You are reading **Chapter 9 · State, Router & Services** (2 of 4).
@@ -0,0 +1,88 @@
1
+ # Storage
2
+
3
+ ## Overview
4
+ `Storage` is the **persistent** store, backed by `localStorage`. Data survives browser restarts until it is cleared — this is the layer for preferences, drafts, or saved documents. It works with strings, numbers, booleans, arrays, and objects.
5
+
6
+ ## When to use
7
+ - Remember settings and user data between visits.
8
+ - Cache what the user has written (drafts, recent items) across reloads.
9
+ - Pair with [Session](Session.md) for short-lived data and [RamStore](RamStore.md) for live reactive state.
10
+
11
+ ## Import
12
+
13
+ ```javascript
14
+ import { saveData, getData, Storage } from "flet-box";
15
+ ```
16
+
17
+ Every function also exists as a method of the exported `Storage` object. The API mirrors [RamStore](RamStore.md) and [Session](Session.md) so you can swap the layer without rewriting your calls.
18
+
19
+ ## Functions
20
+
21
+ | Function | Signature | Returns | Description |
22
+ | --- | --- | --- | --- |
23
+ | `saveData` | `saveData(key, value)` | `boolean` | Persist `value` under `key` in `localStorage`. |
24
+ | `getData` | `getData(key)` | `T \| null` | Read the value (async-safe wrapper). |
25
+ | `getDataSync` | `getDataSync(key)` | `T \| null` | Read the value synchronously. |
26
+ | `updateData` | `updateData(key, value)` | `boolean` | Replace the value. |
27
+ | `deleteData` | `deleteData(key)` | `boolean` | Remove one key. |
28
+ | `clearAllData` | `clearAllData()` | `boolean` | Remove every key. |
29
+ | `hasData` | `hasData(key)` | `boolean` | Is the key present? |
30
+ | `getAllKeys` | `getAllKeys()` | `string[]` | All stored keys. |
31
+ | `getAllData` | `getAllData()` | `Record<string, any>` | Every key/value pair. |
32
+ | `getStorageSize` | `getStorageSize()` | `number` | Approximate size in bytes. |
33
+ | `deleteDataByPrefix` | `deleteDataByPrefix(prefix)` | `number` | Delete every key starting with `prefix`; returns the count. |
34
+ | `deleteDataBySuffix` | `deleteDataBySuffix(suffix)` | `number` | Delete every key ending with `suffix`; returns the count. |
35
+ | `getItemCount` | `getItemCount()` | `number` | How many keys are stored. |
36
+ | `isStorageAvailable` | `isStorageAvailable()` | `boolean` | Is `localStorage` available? |
37
+
38
+ ## Examples
39
+
40
+ ### Everyday example
41
+
42
+ ```javascript
43
+ import { saveData, getData } from "flet-box";
44
+
45
+ saveData("settings", { theme: "dark", fontSize: 18 });
46
+ const settings = getData("settings");
47
+ ```
48
+
49
+ ### Full example
50
+
51
+ ```javascript
52
+ import { saveData, getDataSync, hasData, deleteDataByPrefix } from "flet-box";
53
+
54
+ if (!hasData("drafts")) {
55
+ saveData("drafts", []);
56
+ }
57
+
58
+ saveData("drafts.1", "WIP chapter");
59
+ saveData("drafts.2", "README draft");
60
+
61
+ getDataSync("drafts.1"); // "WIP chapter"
62
+
63
+ // clean up this feature's keys:
64
+ deleteDataByPrefix("drafts.");
65
+ ```
66
+
67
+ ## Notes
68
+
69
+ - Data survives restarts and new tabs, until you remove it. It is shared across tabs of the same origin.
70
+ - Objects and arrays are serialized (and restored) as JSON automatically.
71
+ - `localStorage` is limited (about 5 MB per origin) and synchronous — keep the values small.
72
+ - Use `getDataSync` when you need the value immediately.
73
+ - **Security.** Never store passwords, private keys, or security tokens in browser storage — it is readable by anyone with access to the device. Protect sensitive data with server-side authorization.
74
+
75
+ ## Related pages
76
+ - [RamStore](RamStore.md) — the in-memory reactive store.
77
+ - [Session](Session.md) — tab-scoped persistence.
78
+ - [Frontend services guide](../guides/frontend-services.md) — choosing a storage layer.
79
+
80
+ ---
81
+
82
+ ## Continue reading
83
+
84
+ - **Previous:** [Session](Session.md)
85
+ - **Next:** [HTTP client](http.md)
86
+ - **Index:** [Services index](README.md) · [The FletBox Book](../README.md)
87
+
88
+ You are reading **Chapter 9 · State, Router & Services** (3 of 4).
@@ -0,0 +1,86 @@
1
+ # HTTP client
2
+
3
+ ## Overview
4
+ FletBox ships a small `fetch`-based HTTP client. Five shortcuts — `httpGet`, `httpPost`, `httpPut`, `httpPatch`, `httpDelete` — and one generic function, `httpRequest`, handle requests with JSON bodies, query parameters, custom headers, and timeouts. Every call returns a `Promise`.
5
+
6
+ ## When to use
7
+ - Talk to a REST API from your FletBox app.
8
+ - Stick to one consistent client instead of wrapping `fetch` yourself.
9
+
10
+ ## Import
11
+
12
+ ```javascript
13
+ import { httpGet, httpPost, httpRequest } from "flet-box";
14
+ ```
15
+
16
+ ## Options
17
+
18
+ `options` is an object (the type is `HttpRequestOptions`) that extends the browser `RequestInit`:
19
+
20
+ | Option | Type | Description |
21
+ | --- | --- | --- |
22
+ | `body` | any | Request body. Objects/arrays are JSON-stringified automatically when you pass them (set `Content-Type: application/json`). |
23
+ | `headers` | `Record<string, string>` | Extra headers merged with the defaults. |
24
+ | `params` | `Record<string, string \| number \| boolean \| null \| undefined>` | Query parameters appended to the URL. |
25
+ | `timeout` | number | Abort the request after this many ms. |
26
+ | …plus `RequestInit` | — | `method`, `credentials`, `mode`, `signal`, etc. |
27
+
28
+ ## Functions
29
+
30
+ | Function | Signature | Returns | Description |
31
+ | --- | --- | --- | --- |
32
+ | `httpRequest` | `httpRequest(method, url, options?)` | `Promise<T>` | Any HTTP method with full options. |
33
+ | `httpGet` | `httpGet(url, options?)` | `Promise<T>` | `GET` shortcut. |
34
+ | `httpPost` | `httpPost(url, options?)` | `Promise<T>` | `POST` shortcut. |
35
+ | `httpPut` | `httpPut(url, options?)` | `Promise<T>` | `PUT` shortcut. |
36
+ | `httpPatch` | `httpPatch(url, options?)` | `Promise<T>` | `PATCH` shortcut. |
37
+ | `httpDelete` | `httpDelete(url, options?)` | `Promise<T>` | `DELETE` shortcut. |
38
+
39
+ ## Examples
40
+
41
+ ### Everyday example
42
+
43
+ ```javascript
44
+ import { httpGet, httpPost } from "flet-box";
45
+
46
+ const users = await httpGet("/api/users");
47
+ const created = await httpPost("/api/users", {
48
+ body: { name: "Ada" },
49
+ headers: { "Content-Type": "application/json" },
50
+ });
51
+ ```
52
+
53
+ ### Full example
54
+
55
+ ```javascript
56
+ import { httpGet } from "flet-box";
57
+
58
+ const result = await httpGet("https://api.example.com/search", {
59
+ params: { q: "fletbox", page: 1, perPage: 20 },
60
+ timeout: 8000, // give up after 8 seconds
61
+ });
62
+
63
+ console.log(result.items);
64
+ ```
65
+
66
+ ## Notes
67
+
68
+ - Responses are parsed as JSON automatically when possible.
69
+ - `params` values are appended as query strings; `null`/`undefined` values are skipped.
70
+ - A `timeout` aborts the request with an error once the time is reached.
71
+ - The client depends only on the browser `fetch` API — no external library.
72
+
73
+ ## Related pages
74
+ - [Frontend services guide](../guides/frontend-services.md) — choosing storage vs. network.
75
+ - [Frontend services](../services/README.md) — the full services map.
76
+ - [Tools](../tools/README.md) — the helper functions (next chapter).
77
+
78
+ ---
79
+
80
+ ## Continue reading
81
+
82
+ - **Previous:** [Storage](Storage.md)
83
+ - **Next:** [Tools index](../tools/README.md) — Chapter 10
84
+ - **Index:** [Services index](README.md) · [The FletBox Book](../README.md)
85
+
86
+ You are reading **Chapter 9 · State, Router & Services** (4 of 4).