@affectively/aeon-pages-runtime 0.5.2 → 0.7.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/README.md ADDED
@@ -0,0 +1,399 @@
1
+ # @affectively/aeon-pages-runtime
2
+
3
+ Edge-first rendering runtime for Aeon-Flux with Edge Side Inference (ESI), hyperpersonalized routing, and real-time collaboration.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add @affectively/aeon-pages-runtime
9
+ ```
10
+
11
+ ## Features
12
+
13
+ ### Edge Side Inference (ESI)
14
+
15
+ AI-powered personalization at render time. Components that adapt to user context before reaching the browser.
16
+
17
+ ```tsx
18
+ import { ESI, ESIProvider } from '@affectively/aeon-pages-runtime/router';
19
+
20
+ function App() {
21
+ return (
22
+ <ESIProvider>
23
+ {/* AI-generated personalized greeting */}
24
+ <ESI.Infer prompt="Greet the user based on time of day">
25
+ {(greeting) => <h1>{greeting}</h1>}
26
+ </ESI.Infer>
27
+
28
+ {/* Tier-gated content */}
29
+ <ESI.TierGate tier="premium">
30
+ <PremiumFeatures />
31
+ </ESI.TierGate>
32
+
33
+ {/* Emotion-aware content */}
34
+ <ESI.EmotionGate emotions={['calm', 'content']}>
35
+ <RelaxingContent />
36
+ </ESI.EmotionGate>
37
+ </ESIProvider>
38
+ );
39
+ }
40
+ ```
41
+
42
+ ### AI Translation
43
+
44
+ Automatic translation at the edge. Supports 33 languages with LLM-based translation.
45
+
46
+ ```tsx
47
+ import { ESI, TranslationProvider } from '@affectively/aeon-pages-runtime/router';
48
+
49
+ // App-wide translation with user's preferred language
50
+ function App() {
51
+ return (
52
+ <TranslationProvider defaultLanguage="es">
53
+ <ESI.Translate>Welcome to our platform</ESI.Translate>
54
+ {/* Renders: "Bienvenido a nuestra plataforma" */}
55
+ </TranslationProvider>
56
+ );
57
+ }
58
+
59
+ // Explicit target language
60
+ <ESI.Translate targetLanguage="ja">Hello world</ESI.Translate>
61
+ // Renders: "こんにちは世界"
62
+
63
+ // With context for better translation quality
64
+ <ESI.Translate
65
+ targetLanguage="fr"
66
+ context="emotional wellness app"
67
+ >
68
+ We're here to help you understand your feelings.
69
+ </ESI.Translate>
70
+ ```
71
+
72
+ #### Data-Attribute Translation
73
+
74
+ Automatically translate any element with `data-translate`:
75
+
76
+ ```html
77
+ <p data-translate data-target-lang="es">Hello world</p>
78
+ <!-- Becomes: "Hola mundo" -->
79
+
80
+ <span data-translate data-translate-context="formal, business">
81
+ Please review the attached document.
82
+ </span>
83
+ ```
84
+
85
+ ```tsx
86
+ import { useTranslationObserver } from '@affectively/aeon-pages-runtime/router';
87
+
88
+ function App() {
89
+ // Automatically translates all data-translate elements
90
+ useTranslationObserver({ defaultTargetLanguage: 'es' });
91
+
92
+ return <div data-translate>Hello</div>;
93
+ }
94
+ ```
95
+
96
+ #### Language Configuration Priority
97
+
98
+ 1. `ESI.Translate` `targetLanguage` prop
99
+ 2. `TranslationProvider` context
100
+ 3. `window.__AEON_ESI_STATE__.preferences.language`
101
+ 4. `<meta name="aeon-language" content="es">`
102
+ 5. User preferences
103
+ 6. Browser `navigator.language`
104
+
105
+ #### Supported Languages
106
+
107
+ `en`, `es`, `fr`, `de`, `it`, `pt`, `nl`, `pl`, `ru`, `zh`, `ja`, `ko`, `ar`, `hi`, `bn`, `vi`, `th`, `tr`, `id`, `ms`, `tl`, `sv`, `da`, `no`, `fi`, `cs`, `el`, `he`, `uk`, `ro`, `hu`, `ca`, `hy`
108
+
109
+ ### Hyperpersonalized Routing
110
+
111
+ Routes adapt to user context: time, location, emotion state, and tier.
112
+
113
+ ```tsx
114
+ import { HeuristicAdapter } from '@affectively/aeon-pages-runtime/router';
115
+
116
+ const adapter = new HeuristicAdapter({
117
+ tierFeatures: {
118
+ free: { maxAIInferences: 5 },
119
+ premium: { maxAIInferences: 100 },
120
+ },
121
+ });
122
+
123
+ // Route decision based on user context
124
+ const decision = await adapter.decide(userContext, '/dashboard');
125
+ // Returns: layout, theme, skeleton hints, prefetch suggestions
126
+ ```
127
+
128
+ ### Speculative Pre-rendering
129
+
130
+ Pages render before you click. Zero perceived latency.
131
+
132
+ ```tsx
133
+ import { SpeculationManager, autoInitSpeculation } from '@affectively/aeon-pages-runtime/router';
134
+
135
+ // Auto-initialize based on browser support
136
+ autoInitSpeculation();
137
+
138
+ // Or manual control
139
+ const speculation = new SpeculationManager({
140
+ prefetchUrls: ['/dashboard', '/settings'],
141
+ prerenderUrls: ['/about'],
142
+ });
143
+ speculation.start();
144
+ ```
145
+
146
+ ### ESI Control Components
147
+
148
+ Declarative control flow with AI-powered conditions.
149
+
150
+ ```tsx
151
+ import { ESI } from '@affectively/aeon-pages-runtime/router';
152
+
153
+ // Conditional rendering
154
+ <ESI.If condition="user.tier === 'premium'">
155
+ <PremiumBadge />
156
+ </ESI.If>
157
+
158
+ // Pattern matching
159
+ <ESI.Match value={userEmotion}>
160
+ <ESI.Case when="happy"><HappyContent /></ESI.Case>
161
+ <ESI.Case when="sad"><SupportContent /></ESI.Case>
162
+ <ESI.Default><NeutralContent /></ESI.Default>
163
+ </ESI.Match>
164
+
165
+ // Time-based gates
166
+ <ESI.TimeGate hours={{ start: 9, end: 17 }}>
167
+ <BusinessHoursContent />
168
+ </ESI.TimeGate>
169
+
170
+ // A/B Testing
171
+ <ESI.ABTest variants={['control', 'variant-a', 'variant-b']}>
172
+ {(variant) => <Component variant={variant} />}
173
+ </ESI.ABTest>
174
+ ```
175
+
176
+ ### Cyrano Whisper Channel
177
+
178
+ AI assistant guidance with contextual awareness.
179
+
180
+ ```tsx
181
+ import { esiCyrano, esiHalo } from '@affectively/aeon-pages-runtime/router';
182
+
183
+ // Generate AI whisper for user guidance
184
+ const whisper = esiCyrano({
185
+ intent: 'guide',
186
+ tone: 'warm',
187
+ context: sessionContext,
188
+ });
189
+
190
+ // Halo insights for behavioral patterns
191
+ const insight = esiHalo({
192
+ observation: 'user-hesitation',
193
+ action: 'offer-help',
194
+ });
195
+ ```
196
+
197
+ ### Merkle-Based UCAN Capabilities
198
+
199
+ Fine-grained access control to component nodes using Merkle hashes. Integrates with UCAN tokens for cryptographic authorization.
200
+
201
+ ```tsx
202
+ import {
203
+ createNodeCapabilityVerifier,
204
+ createNodeReadCapability,
205
+ createTreeCapability,
206
+ checkNodeAccess,
207
+ } from '@affectively/aeon-pages-runtime';
208
+
209
+ // Create capabilities for specific nodes by Merkle hash
210
+ const readCapability = createNodeReadCapability('a1b2c3d4e5f6');
211
+ // { can: 'aeon:node:read', with: 'merkle:a1b2c3d4e5f6' }
212
+
213
+ // Create tree capability (grants access to node and all descendants)
214
+ const treeCapability = createTreeCapability('a1b2c3d4e5f6');
215
+ // { can: 'aeon:node:*', with: 'tree:a1b2c3d4e5f6' }
216
+
217
+ // Create path-based capability (grants access to all nodes on a route)
218
+ const pathCapability = createPathCapability('/dashboard/*');
219
+ // { can: 'aeon:node:*', with: 'path:/dashboard/*' }
220
+
221
+ // Verify access to a specific node
222
+ const canAccess = checkNodeAccess(
223
+ userCapabilities,
224
+ { merkleHash: 'a1b2c3d4e5f6', routePath: '/dashboard' },
225
+ 'read'
226
+ );
227
+ ```
228
+
229
+ #### Resource Formats
230
+
231
+ | Format | Example | Description |
232
+ |--------|---------|-------------|
233
+ | `merkle:<hash>` | `merkle:a1b2c3d4e5f6` | Exact match on Merkle hash |
234
+ | `tree:<hash>` | `tree:a1b2c3d4e5f6` | Match node or any ancestor |
235
+ | `path:<route>` | `path:/dashboard/*` | All nodes on a route (wildcards) |
236
+ | `*` | `*` | Match any node (wildcard) |
237
+
238
+ #### Capability Actions
239
+
240
+ | Action | Description |
241
+ |--------|-------------|
242
+ | `aeon:node:read` | Read access to node |
243
+ | `aeon:node:write` | Write access to node |
244
+ | `aeon:node:*` | Full access to node |
245
+
246
+ #### Creating a Verifier from UCAN Token
247
+
248
+ ```tsx
249
+ import { createNodeCapabilityVerifier } from '@affectively/aeon-pages-runtime';
250
+
251
+ const verifier = createNodeCapabilityVerifier(token, {
252
+ extractCapabilities: async (t) => {
253
+ const decoded = await decodeUCAN(t);
254
+ return decoded.capabilities;
255
+ },
256
+ verifyToken: async (t) => {
257
+ return await verifyUCANSignature(t);
258
+ },
259
+ });
260
+
261
+ // Check if user can read a specific node
262
+ const canRead = await verifier(
263
+ { merkleHash: 'a1b2c3d4e5f6' },
264
+ 'read'
265
+ );
266
+
267
+ // Check with full tree path context
268
+ const canWrite = await verifier(
269
+ {
270
+ merkleHash: 'a1b2c3d4e5f6',
271
+ treePath: ['root', 'layout', 'header', 'button'],
272
+ ancestorHashes: ['f1e2d3c4b5a6', 'b2c3d4e5f6a1'],
273
+ routePath: '/dashboard',
274
+ },
275
+ 'write'
276
+ );
277
+ ```
278
+
279
+ #### Integration with Analytics
280
+
281
+ Merkle capabilities integrate seamlessly with `@affectively/aeon-pages-analytics`:
282
+
283
+ ```tsx
284
+ import { buildMerkleTreeSync } from '@affectively/aeon-pages-analytics';
285
+ import { checkNodeAccess } from '@affectively/aeon-pages-runtime';
286
+
287
+ // Build Merkle tree from component tree
288
+ const merkleTree = buildMerkleTreeSync(componentTree);
289
+
290
+ // Check access for each node
291
+ for (const [nodeId, merkleNode] of merkleTree) {
292
+ const canEdit = checkNodeAccess(
293
+ userCapabilities,
294
+ {
295
+ merkleHash: merkleNode.hash,
296
+ treePath: merkleNode.path,
297
+ routePath: currentRoute,
298
+ },
299
+ 'write'
300
+ );
301
+
302
+ if (canEdit) {
303
+ // Show edit controls for this node
304
+ }
305
+ }
306
+ ```
307
+
308
+ ## API Reference
309
+
310
+ ### Components
311
+
312
+ | Component | Description |
313
+ |-----------|-------------|
314
+ | `ESI.Provider` | Root ESI context provider |
315
+ | `ESI.Infer` | AI inference at render time |
316
+ | `ESI.Translate` | Automatic translation |
317
+ | `ESI.TranslationProvider` | App-wide translation context |
318
+ | `ESI.TierGate` | Tier-based content gating |
319
+ | `ESI.EmotionGate` | Emotion-based content gating |
320
+ | `ESI.TimeGate` | Time-based content gating |
321
+ | `ESI.If` / `ESI.Show` / `ESI.Hide` | Conditional rendering |
322
+ | `ESI.Match` / `ESI.Case` | Pattern matching |
323
+ | `ESI.ABTest` | A/B testing |
324
+ | `ESI.ForEach` | AI-powered iteration |
325
+ | `ESI.Select` | AI-powered selection |
326
+
327
+ ### Hooks
328
+
329
+ | Hook | Description |
330
+ |------|-------------|
331
+ | `useESI()` | Access ESI context and processing |
332
+ | `useESIInfer()` | AI inference hook |
333
+ | `useTranslation()` | Translation context access |
334
+ | `useTranslationObserver()` | Auto-translate data-attribute elements |
335
+ | `useGlobalESIState()` | Access global ESI state |
336
+ | `useESITier()` | Get current user tier |
337
+ | `useESIEmotionState()` | Get current emotion state |
338
+
339
+ ### Functions
340
+
341
+ | Function | Description |
342
+ |----------|-------------|
343
+ | `esiTranslate()` | Create translation directive |
344
+ | `translateWithAIGateway()` | Direct AI Gateway translation |
345
+ | `normalizeLanguageCode()` | Normalize language code |
346
+ | `getSupportedLanguages()` | Get list of supported languages |
347
+ | `initTranslationObserver()` | Auto-init DOM translation observer |
348
+
349
+ ### Merkle Capability Functions
350
+
351
+ | Function | Description |
352
+ |----------|-------------|
353
+ | `createNodeReadCapability(hash)` | Create read capability for a Merkle hash |
354
+ | `createNodeWriteCapability(hash)` | Create write capability for a Merkle hash |
355
+ | `createTreeCapability(hash, action)` | Create tree capability (node + descendants) |
356
+ | `createPathCapability(path, action)` | Create path-based capability |
357
+ | `createWildcardNodeCapability(action)` | Create wildcard capability (all nodes) |
358
+ | `createNodeCapabilityVerifier(token, opts)` | Create verifier from UCAN token |
359
+ | `checkNodeAccess(caps, request, action)` | Check if capabilities grant access |
360
+ | `filterAccessibleNodes(nodes, caps, action)` | Filter nodes by access |
361
+ | `getMostSpecificCapability(caps, request)` | Get most specific matching capability |
362
+ | `parseResource(resource)` | Parse resource identifier |
363
+ | `formatResource(type, value)` | Format resource identifier |
364
+ | `capabilityGrantsAccess(cap, request, action)` | Check single capability |
365
+
366
+ ## Configuration
367
+
368
+ ### Head Meta Tags
369
+
370
+ ```html
371
+ <!-- Default translation language -->
372
+ <meta name="aeon-language" content="es">
373
+
374
+ <!-- Translation endpoint -->
375
+ <meta name="aeon-translation-endpoint" content="https://ai-gateway.example.com">
376
+
377
+ <!-- Cache TTL in seconds -->
378
+ <meta name="aeon-translation-cache-ttl" content="86400">
379
+ ```
380
+
381
+ ### ESI State
382
+
383
+ Global state is available at `window.__AEON_ESI_STATE__`:
384
+
385
+ ```typescript
386
+ interface GlobalESIState {
387
+ tier: 'free' | 'premium' | 'enterprise';
388
+ emotion: EmotionState;
389
+ preferences: {
390
+ language: string;
391
+ theme: 'light' | 'dark' | 'system';
392
+ };
393
+ features: Record<string, boolean>;
394
+ }
395
+ ```
396
+
397
+ ## License
398
+
399
+ MIT