@affectively/aeon-pages 1.3.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 +112 -0
- package/README.md +625 -0
- package/examples/basic/aeon.config.ts +39 -0
- package/examples/basic/components/Cursor.tsx +86 -0
- package/examples/basic/components/OfflineIndicator.tsx +103 -0
- package/examples/basic/components/PresenceBar.tsx +77 -0
- package/examples/basic/package.json +20 -0
- package/examples/basic/pages/index.tsx +80 -0
- package/package.json +101 -0
- package/packages/analytics/README.md +309 -0
- package/packages/analytics/build.ts +35 -0
- package/packages/analytics/package.json +50 -0
- package/packages/analytics/src/click-tracker.ts +368 -0
- package/packages/analytics/src/context-bridge.ts +319 -0
- package/packages/analytics/src/data-layer.ts +302 -0
- package/packages/analytics/src/gtm-loader.ts +239 -0
- package/packages/analytics/src/index.ts +230 -0
- package/packages/analytics/src/merkle-tree.ts +489 -0
- package/packages/analytics/src/provider.tsx +300 -0
- package/packages/analytics/src/types.ts +320 -0
- package/packages/analytics/src/use-analytics.ts +296 -0
- package/packages/analytics/tsconfig.json +19 -0
- package/packages/benchmarks/src/benchmark.test.ts +691 -0
- package/packages/cli/dist/index.js +61899 -0
- package/packages/cli/package.json +43 -0
- package/packages/cli/src/commands/build.test.ts +682 -0
- package/packages/cli/src/commands/build.ts +890 -0
- package/packages/cli/src/commands/dev.ts +473 -0
- package/packages/cli/src/commands/init.ts +409 -0
- package/packages/cli/src/commands/start.ts +297 -0
- package/packages/cli/src/index.ts +105 -0
- package/packages/directives/src/use-aeon.ts +272 -0
- package/packages/mcp-server/package.json +51 -0
- package/packages/mcp-server/src/index.ts +178 -0
- package/packages/mcp-server/src/resources.ts +346 -0
- package/packages/mcp-server/src/tools/index.ts +36 -0
- package/packages/mcp-server/src/tools/navigation.ts +545 -0
- package/packages/mcp-server/tsconfig.json +21 -0
- package/packages/react/package.json +40 -0
- package/packages/react/src/Link.tsx +388 -0
- package/packages/react/src/components/InstallPrompt.tsx +286 -0
- package/packages/react/src/components/OfflineDiagnostics.tsx +677 -0
- package/packages/react/src/components/PushNotifications.tsx +453 -0
- package/packages/react/src/hooks/useAeonNavigation.ts +219 -0
- package/packages/react/src/hooks/useConflicts.ts +277 -0
- package/packages/react/src/hooks/useNetworkState.ts +209 -0
- package/packages/react/src/hooks/usePilotNavigation.ts +254 -0
- package/packages/react/src/hooks/useServiceWorker.ts +278 -0
- package/packages/react/src/hooks.ts +195 -0
- package/packages/react/src/index.ts +151 -0
- package/packages/react/src/provider.tsx +467 -0
- package/packages/react/tsconfig.json +19 -0
- package/packages/runtime/README.md +399 -0
- package/packages/runtime/build.ts +48 -0
- package/packages/runtime/package.json +71 -0
- package/packages/runtime/schema.sql +40 -0
- package/packages/runtime/src/api-routes.ts +465 -0
- package/packages/runtime/src/benchmark.ts +171 -0
- package/packages/runtime/src/cache.ts +479 -0
- package/packages/runtime/src/durable-object.ts +1341 -0
- package/packages/runtime/src/index.ts +360 -0
- package/packages/runtime/src/navigation.test.ts +421 -0
- package/packages/runtime/src/navigation.ts +422 -0
- package/packages/runtime/src/nextjs-adapter.ts +272 -0
- package/packages/runtime/src/offline/encrypted-queue.test.ts +607 -0
- package/packages/runtime/src/offline/encrypted-queue.ts +478 -0
- package/packages/runtime/src/offline/encryption.test.ts +412 -0
- package/packages/runtime/src/offline/encryption.ts +397 -0
- package/packages/runtime/src/offline/types.ts +465 -0
- package/packages/runtime/src/predictor.ts +371 -0
- package/packages/runtime/src/registry.ts +351 -0
- package/packages/runtime/src/router/context-extractor.ts +661 -0
- package/packages/runtime/src/router/esi-control-react.tsx +2053 -0
- package/packages/runtime/src/router/esi-control.ts +541 -0
- package/packages/runtime/src/router/esi-cyrano.ts +779 -0
- package/packages/runtime/src/router/esi-format-react.tsx +1744 -0
- package/packages/runtime/src/router/esi-react.tsx +1065 -0
- package/packages/runtime/src/router/esi-translate-observer.ts +476 -0
- package/packages/runtime/src/router/esi-translate-react.tsx +556 -0
- package/packages/runtime/src/router/esi-translate.ts +503 -0
- package/packages/runtime/src/router/esi.ts +666 -0
- package/packages/runtime/src/router/heuristic-adapter.test.ts +295 -0
- package/packages/runtime/src/router/heuristic-adapter.ts +557 -0
- package/packages/runtime/src/router/index.ts +298 -0
- package/packages/runtime/src/router/merkle-capability.ts +473 -0
- package/packages/runtime/src/router/speculation.ts +451 -0
- package/packages/runtime/src/router/types.ts +630 -0
- package/packages/runtime/src/router.test.ts +470 -0
- package/packages/runtime/src/router.ts +302 -0
- package/packages/runtime/src/server.ts +481 -0
- package/packages/runtime/src/service-worker-push.ts +319 -0
- package/packages/runtime/src/service-worker.ts +553 -0
- package/packages/runtime/src/skeleton-hydrate.ts +237 -0
- package/packages/runtime/src/speculation.test.ts +389 -0
- package/packages/runtime/src/speculation.ts +486 -0
- package/packages/runtime/src/storage.test.ts +1297 -0
- package/packages/runtime/src/storage.ts +1048 -0
- package/packages/runtime/src/sync/conflict-resolver.test.ts +528 -0
- package/packages/runtime/src/sync/conflict-resolver.ts +565 -0
- package/packages/runtime/src/sync/coordinator.test.ts +608 -0
- package/packages/runtime/src/sync/coordinator.ts +596 -0
- package/packages/runtime/src/tree-compiler.ts +295 -0
- package/packages/runtime/src/types.ts +728 -0
- package/packages/runtime/src/worker.ts +327 -0
- package/packages/runtime/tsconfig.json +20 -0
- package/packages/runtime/wasm/aeon_pages_runtime.d.ts +504 -0
- package/packages/runtime/wasm/aeon_pages_runtime.js +1657 -0
- package/packages/runtime/wasm/aeon_pages_runtime_bg.wasm +0 -0
- package/packages/runtime/wasm/aeon_pages_runtime_bg.wasm.d.ts +196 -0
- package/packages/runtime/wasm/package.json +21 -0
- package/packages/runtime/wrangler.toml +41 -0
- package/packages/runtime-wasm/Cargo.lock +436 -0
- package/packages/runtime-wasm/Cargo.toml +29 -0
- package/packages/runtime-wasm/pkg/aeon_pages_runtime.d.ts +480 -0
- package/packages/runtime-wasm/pkg/aeon_pages_runtime.js +1568 -0
- package/packages/runtime-wasm/pkg/aeon_pages_runtime_bg.wasm +0 -0
- package/packages/runtime-wasm/pkg/aeon_pages_runtime_bg.wasm.d.ts +192 -0
- package/packages/runtime-wasm/pkg/package.json +21 -0
- package/packages/runtime-wasm/src/hydrate.rs +352 -0
- package/packages/runtime-wasm/src/lib.rs +191 -0
- package/packages/runtime-wasm/src/render.rs +629 -0
- package/packages/runtime-wasm/src/router.rs +298 -0
- package/packages/runtime-wasm/src/skeleton.rs +430 -0
- package/rfcs/RFC-001-ZERO-DEPENDENCY-RENDERING.md +1446 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
//! Aeon Pages WASM Runtime
|
|
2
|
+
//!
|
|
3
|
+
//! Lightweight router and component hydration for @affectively/aeon-pages.
|
|
4
|
+
//! Compiles to ~20KB WASM for edge/browser deployment.
|
|
5
|
+
|
|
6
|
+
use wasm_bindgen::prelude::*;
|
|
7
|
+
use serde::{Deserialize, Serialize};
|
|
8
|
+
use std::collections::HashMap;
|
|
9
|
+
|
|
10
|
+
mod router;
|
|
11
|
+
mod hydrate;
|
|
12
|
+
mod render;
|
|
13
|
+
mod skeleton;
|
|
14
|
+
|
|
15
|
+
pub use router::*;
|
|
16
|
+
pub use hydrate::*;
|
|
17
|
+
pub use render::*;
|
|
18
|
+
pub use skeleton::*;
|
|
19
|
+
|
|
20
|
+
#[wasm_bindgen(start)]
|
|
21
|
+
pub fn init() {
|
|
22
|
+
#[cfg(feature = "console_error_panic_hook")]
|
|
23
|
+
console_error_panic_hook::set_once();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/// Route definition from the build manifest
|
|
27
|
+
#[wasm_bindgen]
|
|
28
|
+
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
29
|
+
pub struct RouteDefinition {
|
|
30
|
+
/// Pattern like "/blog/[slug]" or "/api/[...path]"
|
|
31
|
+
pattern: String,
|
|
32
|
+
/// Session ID template, e.g., "blog-$slug"
|
|
33
|
+
session_id: String,
|
|
34
|
+
/// Component ID reference
|
|
35
|
+
component_id: String,
|
|
36
|
+
/// Optional layout wrapper
|
|
37
|
+
layout: Option<String>,
|
|
38
|
+
/// Whether this route uses 'use aeon' directive
|
|
39
|
+
is_aeon: bool,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
#[wasm_bindgen]
|
|
43
|
+
impl RouteDefinition {
|
|
44
|
+
#[wasm_bindgen(constructor)]
|
|
45
|
+
pub fn new(
|
|
46
|
+
pattern: String,
|
|
47
|
+
session_id: String,
|
|
48
|
+
component_id: String,
|
|
49
|
+
layout: Option<String>,
|
|
50
|
+
is_aeon: bool,
|
|
51
|
+
) -> Self {
|
|
52
|
+
Self {
|
|
53
|
+
pattern,
|
|
54
|
+
session_id,
|
|
55
|
+
component_id,
|
|
56
|
+
layout,
|
|
57
|
+
is_aeon,
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
#[wasm_bindgen(getter)]
|
|
62
|
+
pub fn pattern(&self) -> String {
|
|
63
|
+
self.pattern.clone()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
#[wasm_bindgen(getter)]
|
|
67
|
+
pub fn session_id(&self) -> String {
|
|
68
|
+
self.session_id.clone()
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
#[wasm_bindgen(getter)]
|
|
72
|
+
pub fn component_id(&self) -> String {
|
|
73
|
+
self.component_id.clone()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
#[wasm_bindgen(getter)]
|
|
77
|
+
pub fn layout(&self) -> Option<String> {
|
|
78
|
+
self.layout.clone()
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
#[wasm_bindgen(getter)]
|
|
82
|
+
pub fn is_aeon(&self) -> bool {
|
|
83
|
+
self.is_aeon
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/// Match result with extracted parameters
|
|
88
|
+
#[wasm_bindgen]
|
|
89
|
+
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
90
|
+
pub struct RouteMatch {
|
|
91
|
+
/// The matched route definition
|
|
92
|
+
route: RouteDefinition,
|
|
93
|
+
/// Extracted parameters from dynamic segments
|
|
94
|
+
params: HashMap<String, String>,
|
|
95
|
+
/// The resolved session ID with params substituted
|
|
96
|
+
resolved_session_id: String,
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
#[wasm_bindgen]
|
|
100
|
+
impl RouteMatch {
|
|
101
|
+
#[wasm_bindgen(getter)]
|
|
102
|
+
pub fn route(&self) -> RouteDefinition {
|
|
103
|
+
self.route.clone()
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
#[wasm_bindgen(getter)]
|
|
107
|
+
pub fn params_json(&self) -> String {
|
|
108
|
+
serde_json::to_string(&self.params).unwrap_or_else(|_| "{}".to_string())
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
#[wasm_bindgen(getter)]
|
|
112
|
+
pub fn resolved_session_id(&self) -> String {
|
|
113
|
+
self.resolved_session_id.clone()
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
pub fn get_param(&self, key: &str) -> Option<String> {
|
|
117
|
+
self.params.get(key).cloned()
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/// Serialized component tree (stored in Aeon sessions)
|
|
122
|
+
#[wasm_bindgen]
|
|
123
|
+
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
124
|
+
pub struct SerializedComponent {
|
|
125
|
+
/// Component type: "div", "Button", "MyComponent"
|
|
126
|
+
#[serde(rename = "type")]
|
|
127
|
+
component_type: String,
|
|
128
|
+
/// Props as JSON
|
|
129
|
+
props: Option<String>,
|
|
130
|
+
/// Children: either strings or nested components
|
|
131
|
+
children: Vec<SerializedChild>,
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
135
|
+
#[serde(untagged)]
|
|
136
|
+
pub enum SerializedChild {
|
|
137
|
+
Text(String),
|
|
138
|
+
Component(Box<SerializedComponent>),
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
#[wasm_bindgen]
|
|
142
|
+
impl SerializedComponent {
|
|
143
|
+
#[wasm_bindgen(constructor)]
|
|
144
|
+
pub fn new(component_type: String, props: Option<String>) -> Self {
|
|
145
|
+
Self {
|
|
146
|
+
component_type,
|
|
147
|
+
props,
|
|
148
|
+
children: Vec::new(),
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
pub fn add_text_child(&mut self, text: String) {
|
|
153
|
+
self.children.push(SerializedChild::Text(text));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
pub fn add_component_child(&mut self, component: SerializedComponent) {
|
|
157
|
+
self.children.push(SerializedChild::Component(Box::new(component)));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
#[wasm_bindgen(getter)]
|
|
161
|
+
pub fn component_type(&self) -> String {
|
|
162
|
+
self.component_type.clone()
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
#[wasm_bindgen(getter)]
|
|
166
|
+
pub fn props(&self) -> Option<String> {
|
|
167
|
+
self.props.clone()
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
pub fn to_json(&self) -> String {
|
|
171
|
+
serde_json::to_string(self).unwrap_or_else(|_| "{}".to_string())
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
pub fn from_json(json: &str) -> Result<SerializedComponent, JsValue> {
|
|
175
|
+
serde_json::from_str(json)
|
|
176
|
+
.map_err(|e| JsValue::from_str(&format!("Failed to parse component: {}", e)))
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/// Log to browser console
|
|
181
|
+
#[wasm_bindgen]
|
|
182
|
+
extern "C" {
|
|
183
|
+
#[wasm_bindgen(js_namespace = console)]
|
|
184
|
+
fn log(s: &str);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/// Helper macro for console logging
|
|
188
|
+
#[macro_export]
|
|
189
|
+
macro_rules! console_log {
|
|
190
|
+
($($t:tt)*) => (log(&format!($($t)*)))
|
|
191
|
+
}
|