@affectively/aeon-pages-runtime 0.1.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.
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Navigation Cache - In-memory cache for total preload navigation
3
+ *
4
+ * With 8.4KB framework + ~2-5KB per page session, we can preload EVERYTHING.
5
+ * Site with 100 pages = ~315KB total (smaller than one hero image!)
6
+ */
7
+ export interface CachedSession {
8
+ sessionId: string;
9
+ route: string;
10
+ tree: unknown;
11
+ data: Record<string, unknown>;
12
+ schemaVersion: string;
13
+ cachedAt: number;
14
+ expiresAt?: number;
15
+ }
16
+ export interface CacheStats {
17
+ size: number;
18
+ totalBytes: number;
19
+ hitRate: number;
20
+ preloadedRoutes: number;
21
+ }
22
+ export interface NavigationCacheOptions {
23
+ maxSize?: number;
24
+ defaultTtl?: number;
25
+ onEvict?: (session: CachedSession) => void;
26
+ }
27
+ export declare class NavigationCache {
28
+ private cache;
29
+ private accessOrder;
30
+ private hits;
31
+ private misses;
32
+ private maxSize;
33
+ private defaultTtl;
34
+ private onEvict?;
35
+ constructor(options?: NavigationCacheOptions);
36
+ /**
37
+ * Get a session from cache
38
+ */
39
+ get(sessionId: string): CachedSession | null;
40
+ /**
41
+ * Store a session in cache
42
+ */
43
+ set(session: CachedSession, ttl?: number): void;
44
+ /**
45
+ * Check if session is cached
46
+ */
47
+ has(sessionId: string): boolean;
48
+ /**
49
+ * Prefetch a session by ID
50
+ */
51
+ prefetch(sessionId: string, fetcher: () => Promise<CachedSession>): Promise<CachedSession>;
52
+ /**
53
+ * Prefetch multiple sessions in parallel
54
+ */
55
+ prefetchMany(sessionIds: string[], fetcher: (sessionId: string) => Promise<CachedSession>): Promise<CachedSession[]>;
56
+ /**
57
+ * Preload all sessions (total preload strategy)
58
+ */
59
+ preloadAll(manifest: {
60
+ sessionId: string;
61
+ route: string;
62
+ }[], fetcher: (sessionId: string) => Promise<CachedSession>, options?: {
63
+ onProgress?: (loaded: number, total: number) => void;
64
+ }): Promise<void>;
65
+ /**
66
+ * Invalidate a cached session
67
+ */
68
+ invalidate(sessionId: string): void;
69
+ /**
70
+ * Clear all cached sessions
71
+ */
72
+ clear(): void;
73
+ /**
74
+ * Get cache statistics
75
+ */
76
+ getStats(): CacheStats;
77
+ /**
78
+ * Get all cached session IDs
79
+ */
80
+ keys(): string[];
81
+ /**
82
+ * Export cache for service worker storage
83
+ */
84
+ export(): CachedSession[];
85
+ /**
86
+ * Import cache from service worker storage
87
+ */
88
+ import(sessions: CachedSession[]): void;
89
+ private evictLRU;
90
+ private updateAccessOrder;
91
+ private removeFromAccessOrder;
92
+ }
93
+ export declare function getNavigationCache(): NavigationCache;
94
+ export declare function setNavigationCache(cache: NavigationCache): void;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Aeon Pages Durable Object
3
+ *
4
+ * This is the Cloudflare Durable Object that provides:
5
+ * - Strong consistency for page sessions
6
+ * - Real-time WebSocket connections for collaboration
7
+ * - Presence tracking across connected clients
8
+ * - CRDT-based conflict resolution
9
+ *
10
+ * Deploy this alongside your Cloudflare Worker.
11
+ */
12
+ interface Env {
13
+ DB?: D1Database;
14
+ }
15
+ interface D1Database {
16
+ prepare(query: string): D1PreparedStatement;
17
+ }
18
+ interface D1PreparedStatement {
19
+ bind(...values: unknown[]): D1PreparedStatement;
20
+ run(): Promise<void>;
21
+ }
22
+ /**
23
+ * Aeon Page Session Durable Object
24
+ *
25
+ * One instance per page session, handles:
26
+ * - Session state (component tree, data)
27
+ * - Real-time presence
28
+ * - WebSocket connections
29
+ * - Collaborative editing
30
+ */
31
+ export declare class AeonPageSession {
32
+ private state;
33
+ private env;
34
+ private sessions;
35
+ private session;
36
+ constructor(state: DurableObjectState, env: Env);
37
+ fetch(request: Request): Promise<Response>;
38
+ private handleWebSocket;
39
+ private handleMessage;
40
+ private broadcast;
41
+ private applyEdit;
42
+ private propagateToD1;
43
+ private handleSessionRequest;
44
+ private handleTreeRequest;
45
+ private handlePresenceRequest;
46
+ private getSession;
47
+ private saveSession;
48
+ }
49
+ /**
50
+ * Aeon Routes Registry Durable Object
51
+ *
52
+ * Singleton that manages the route registry with strong consistency.
53
+ * Used via: namespace.idFromName('__routes__')
54
+ */
55
+ export declare class AeonRoutesRegistry {
56
+ private state;
57
+ private env;
58
+ constructor(state: DurableObjectState, env: Env);
59
+ fetch(request: Request): Promise<Response>;
60
+ private handleRouteRequest;
61
+ private handleRoutesRequest;
62
+ }
63
+ interface DurableObjectState {
64
+ storage: DurableObjectStorage;
65
+ id: DurableObjectId;
66
+ waitUntil(promise: Promise<unknown>): void;
67
+ }
68
+ interface DurableObjectStorage {
69
+ get<T = unknown>(key: string): Promise<T | undefined>;
70
+ put<T>(key: string, value: T): Promise<void>;
71
+ delete(key: string): Promise<boolean>;
72
+ list<T = unknown>(options?: {
73
+ prefix?: string;
74
+ }): Promise<Map<string, T>>;
75
+ }
76
+ interface DurableObjectId {
77
+ toString(): string;
78
+ }
79
+ export {};
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @affectively/aeon-pages-runtime
3
+ *
4
+ * Lightweight runtime for Aeon Pages - the CMS IS the website.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { createAeonServer } from '@affectively/aeon-pages-runtime/server';
9
+ *
10
+ * const server = await createAeonServer({
11
+ * config: {
12
+ * pagesDir: './pages',
13
+ * runtime: 'bun',
14
+ * aeon: {
15
+ * sync: { mode: 'distributed' },
16
+ * presence: { enabled: true },
17
+ * },
18
+ * },
19
+ * });
20
+ *
21
+ * console.log(`Aeon Pages running on port ${server.port}`);
22
+ * ```
23
+ */
24
+ export { createAeonServer } from './server';
25
+ export { AeonRouter } from './router.js';
26
+ export { AeonRouteRegistry } from './registry';
27
+ export { AeonNavigationEngine, getNavigator, setNavigator, } from './navigation';
28
+ export type { NavigationOptions, PrefetchOptions, NavigationState, } from './navigation';
29
+ export { NavigationCache, getNavigationCache, setNavigationCache, } from './cache';
30
+ export type { CachedSession, CacheStats, NavigationCacheOptions, } from './cache';
31
+ export { NavigationPredictor, getPredictor, setPredictor, } from './predictor';
32
+ export type { PredictedRoute, NavigationRecord, CommunityPattern, PredictorConfig, } from './predictor';
33
+ export { createStorageAdapter, FileStorageAdapter, D1StorageAdapter, DurableObjectStorageAdapter, HybridStorageAdapter, DashStorageAdapter, } from './storage';
34
+ export type { StorageAdapter } from './storage';
35
+ export { AeonPageSession, AeonRoutesRegistry } from './durable-object';
36
+ export type { AeonConfig, AeonOptions, SyncOptions, VersioningOptions, PresenceOptions, OfflineOptions, ComponentOptions, OutputOptions, RouteDefinition, RouteMatch, RouteMetadata, RouteOperation, SerializedComponent, PageSession, PresenceInfo, PresenceUser, AeonCapability, } from './types';
37
+ export { DEFAULT_ROUTER_CONFIG, DEFAULT_ESI_CONFIG, HeuristicAdapter, EdgeWorkersESIProcessor, extractUserContext, createContextMiddleware, setContextCookies, addSpeculationHeaders, esiInfer, esiEmbed, esiEmotion, esiVision, esiWithContext, } from './router/index';
38
+ export type { EmotionState, Viewport, ConnectionType, UserTier, UserContext, ThemeMode, LayoutDensity, LayoutType, SkeletonHints, RouteDecision, ComponentNode, ComponentTree, ComponentTreeSchema, RouterAdapter, HeuristicAdapterConfig, TierFeatures, SignalProcessor, ContextExtractorOptions, AIRouterConfig, SpeculationConfig, PersonalizationConfig, RouterConfig, RouterConfigWithESI, ESIModel, ESIContentType, ESIParams, ESIContent, ESIDirective, ESIResult, ESIProcessor, ESIConfig, } from './router/index';
39
+ export declare const VERSION = "0.1.0";