@affectively/aeon-pages-runtime 0.1.0 → 0.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.
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Aeon Pages API Routes
3
+ *
4
+ * Server-side route handling for API endpoints.
5
+ * Enables full-stack functionality without a separate backend.
6
+ */
7
+ import type { AeonEnv, AeonContext, ApiRoute, ApiRouteMatch, ApiRouteModule, ApiRouteHandler, ExecutionContext } from './types';
8
+ /**
9
+ * API Router - matches requests to registered API routes
10
+ */
11
+ export declare class ApiRouter<E extends AeonEnv = AeonEnv> {
12
+ private routes;
13
+ /**
14
+ * Register an API route
15
+ */
16
+ register(pattern: string, module: ApiRouteModule<E>): void;
17
+ /**
18
+ * Register multiple routes from a route map
19
+ */
20
+ registerAll(routes: Record<string, ApiRouteModule<E>>): void;
21
+ /**
22
+ * Match a request to a route
23
+ */
24
+ match(request: Request): ApiRouteMatch | null;
25
+ /**
26
+ * Handle an API request
27
+ */
28
+ handle(request: Request, env: E, ctx: ExecutionContext): Promise<Response | null>;
29
+ /**
30
+ * Parse a route pattern into segments
31
+ */
32
+ private parsePattern;
33
+ /**
34
+ * Match path segments against route segments
35
+ */
36
+ private matchSegments;
37
+ /**
38
+ * Get the handler for a given HTTP method
39
+ */
40
+ private getHandler;
41
+ /**
42
+ * Get all registered routes (for debugging/introspection)
43
+ */
44
+ getRoutes(): ApiRoute[];
45
+ }
46
+ /**
47
+ * Create a new API router instance
48
+ */
49
+ export declare function createApiRouter<E extends AeonEnv = AeonEnv>(): ApiRouter<E>;
50
+ /**
51
+ * Helper to create a JSON response
52
+ */
53
+ export declare function json<T>(data: T, init?: ResponseInit): Response;
54
+ /**
55
+ * Helper to create a redirect response
56
+ */
57
+ export declare function redirect(url: string, status?: 301 | 302 | 303 | 307 | 308): Response;
58
+ /**
59
+ * Helper to create an error response
60
+ */
61
+ export declare function error(message: string, status?: number): Response;
62
+ /**
63
+ * Helper to create a not found response
64
+ */
65
+ export declare function notFound(message?: string): Response;
66
+ /**
67
+ * Helper to create a bad request response
68
+ */
69
+ export declare function badRequest(message?: string): Response;
70
+ /**
71
+ * Helper to create an unauthorized response
72
+ */
73
+ export declare function unauthorized(message?: string): Response;
74
+ /**
75
+ * Helper to create a forbidden response
76
+ */
77
+ export declare function forbidden(message?: string): Response;
78
+ /** Middleware function type */
79
+ export type Middleware<E extends AeonEnv = AeonEnv> = (context: AeonContext<E>, next: () => Promise<Response>) => Response | Promise<Response>;
80
+ /**
81
+ * Compose multiple middleware into a single handler
82
+ */
83
+ export declare function composeMiddleware<E extends AeonEnv = AeonEnv>(...middlewares: Middleware<E>[]): (handler: ApiRouteHandler<E>) => ApiRouteHandler<E>;
84
+ /**
85
+ * CORS middleware factory
86
+ */
87
+ export declare function cors(options?: {
88
+ origin?: string | string[] | ((origin: string) => boolean);
89
+ methods?: string[];
90
+ headers?: string[];
91
+ credentials?: boolean;
92
+ maxAge?: number;
93
+ }): Middleware;
94
+ /**
95
+ * Auth middleware factory - validates Authorization header
96
+ */
97
+ export declare function requireAuth<E extends AeonEnv = AeonEnv>(validate: (token: string, context: AeonContext<E>) => boolean | Promise<boolean>): Middleware<E>;
98
+ /**
99
+ * Rate limiting middleware (uses KV for distributed rate limiting)
100
+ */
101
+ export declare function rateLimit<E extends AeonEnv = AeonEnv>(options: {
102
+ /** KV namespace key in env */
103
+ kvKey?: keyof E;
104
+ /** Requests per window */
105
+ limit: number;
106
+ /** Window size in seconds */
107
+ window: number;
108
+ /** Function to extract client identifier (default: IP) */
109
+ keyGenerator?: (context: AeonContext<E>) => string;
110
+ }): Middleware<E>;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Aeon Flux Benchmarks
3
+ *
4
+ * Run: bun run src/benchmark.ts
5
+ */
6
+ export {};
package/dist/cache.d.ts CHANGED
@@ -92,3 +92,80 @@ export declare class NavigationCache {
92
92
  }
93
93
  export declare function getNavigationCache(): NavigationCache;
94
94
  export declare function setNavigationCache(cache: NavigationCache): void;
95
+ /** Cached skeleton data for a route */
96
+ export interface CachedSkeleton {
97
+ route: string;
98
+ html: string;
99
+ css: string;
100
+ cachedAt: number;
101
+ expiresAt?: number;
102
+ }
103
+ /** Skeleton cache options */
104
+ export interface SkeletonCacheOptions {
105
+ /** Maximum number of skeletons to cache */
106
+ maxSize?: number;
107
+ /** Default TTL in milliseconds */
108
+ defaultTtl?: number;
109
+ }
110
+ /**
111
+ * Skeleton Cache - Optimized for instant skeleton delivery
112
+ *
113
+ * Skeletons are cached separately from full pages for faster access.
114
+ * In edge environments, skeletons are stored in KV for ~1ms access.
115
+ */
116
+ export declare class SkeletonCache {
117
+ private cache;
118
+ private maxSize;
119
+ private defaultTtl;
120
+ constructor(options?: SkeletonCacheOptions);
121
+ /**
122
+ * Get skeleton for a route
123
+ */
124
+ get(route: string): CachedSkeleton | null;
125
+ /**
126
+ * Store skeleton for a route
127
+ */
128
+ set(skeleton: CachedSkeleton, ttl?: number): void;
129
+ /**
130
+ * Check if skeleton is cached
131
+ */
132
+ has(route: string): boolean;
133
+ /**
134
+ * Invalidate skeleton for a route
135
+ */
136
+ invalidate(route: string): void;
137
+ /**
138
+ * Clear all cached skeletons
139
+ */
140
+ clear(): void;
141
+ /**
142
+ * Get cache size
143
+ */
144
+ get size(): number;
145
+ /**
146
+ * Export all skeletons for service worker
147
+ */
148
+ export(): CachedSkeleton[];
149
+ /**
150
+ * Import skeletons from service worker
151
+ */
152
+ import(skeletons: CachedSkeleton[]): void;
153
+ }
154
+ /** Skeleton and content result for progressive rendering */
155
+ export interface SkeletonWithContent {
156
+ /** Skeleton HTML (available immediately) */
157
+ skeleton: CachedSkeleton | null;
158
+ /** Content promise (resolves later) */
159
+ content: Promise<CachedSession | null>;
160
+ }
161
+ /**
162
+ * Get skeleton and content in parallel for optimal UX
163
+ *
164
+ * @param route - The route to fetch
165
+ * @param skeletonCache - Skeleton cache instance
166
+ * @param sessionCache - Session cache instance
167
+ * @param contentFetcher - Function to fetch full content
168
+ */
169
+ export declare function getWithSkeleton(route: string, skeletonCache: SkeletonCache, sessionCache: NavigationCache, contentFetcher: (route: string) => Promise<CachedSession>): SkeletonWithContent;
170
+ export declare function getSkeletonCache(): SkeletonCache;
171
+ export declare function setSkeletonCache(cache: SkeletonCache): void;
@@ -11,6 +11,14 @@
11
11
  */
12
12
  interface Env {
13
13
  DB?: D1Database;
14
+ GITHUB_TOKEN?: string;
15
+ GITHUB_REPO?: string;
16
+ GITHUB_TREE_PATH?: string;
17
+ GITHUB_BASE_BRANCH?: string;
18
+ GITHUB_DEV_BRANCH?: string;
19
+ GITHUB_AUTO_MERGE?: string;
20
+ GITHUB_WEBHOOK_SECRET?: string;
21
+ SYNC_WEBHOOK_URL?: string;
14
22
  }
15
23
  interface D1Database {
16
24
  prepare(query: string): D1PreparedStatement;
@@ -33,6 +41,7 @@ export declare class AeonPageSession {
33
41
  private env;
34
42
  private sessions;
35
43
  private session;
44
+ private webhooks;
36
45
  constructor(state: DurableObjectState, env: Env);
37
46
  fetch(request: Request): Promise<Response>;
38
47
  private handleWebSocket;
@@ -40,11 +49,64 @@ export declare class AeonPageSession {
40
49
  private broadcast;
41
50
  private applyEdit;
42
51
  private propagateToD1;
52
+ /**
53
+ * Create a GitHub PR when tree changes
54
+ */
55
+ private createTreePR;
56
+ /**
57
+ * Merge a GitHub PR
58
+ */
59
+ private mergePR;
60
+ /**
61
+ * Handle GitHub webhook callbacks (push events)
62
+ * This is called when GitHub pushes changes to the repo
63
+ */
64
+ private handleWebhookEndpoint;
65
+ /**
66
+ * Verify GitHub webhook signature
67
+ */
68
+ private verifyGitHubSignature;
69
+ /**
70
+ * Process GitHub webhook events
71
+ */
72
+ private processGitHubWebhook;
73
+ /**
74
+ * Handle webhook configuration (register/list)
75
+ */
76
+ private handleWebhooksConfig;
77
+ /**
78
+ * Handle version request
79
+ */
80
+ private handleVersionRequest;
81
+ /**
82
+ * Fire webhooks for an event
83
+ */
84
+ private fireWebhook;
43
85
  private handleSessionRequest;
86
+ /**
87
+ * Handle session initialization (POST /init)
88
+ * Creates a new session or returns existing one
89
+ */
90
+ private handleInitRequest;
44
91
  private handleTreeRequest;
45
92
  private handlePresenceRequest;
46
93
  private getSession;
47
94
  private saveSession;
95
+ /**
96
+ * Handle sync queue batch (POST /sync-queue)
97
+ * Receives a batch of offline operations to sync
98
+ */
99
+ private handleSyncQueueRequest;
100
+ /**
101
+ * Handle queue status request (GET /queue-status)
102
+ * Returns pending operations for this session
103
+ */
104
+ private handleQueueStatusRequest;
105
+ /**
106
+ * Handle conflict resolution (POST /resolve-conflict)
107
+ * Manually resolve a detected conflict
108
+ */
109
+ private handleResolveConflictRequest;
48
110
  }
49
111
  /**
50
112
  * Aeon Routes Registry Durable Object
@@ -64,6 +126,7 @@ interface DurableObjectState {
64
126
  storage: DurableObjectStorage;
65
127
  id: DurableObjectId;
66
128
  waitUntil(promise: Promise<unknown>): void;
129
+ blockConcurrencyWhile<T>(callback: () => Promise<T>): Promise<T>;
67
130
  }
68
131
  interface DurableObjectStorage {
69
132
  get<T = unknown>(key: string): Promise<T | undefined>;
package/dist/index.d.ts CHANGED
@@ -25,15 +25,31 @@ export { createAeonServer } from './server';
25
25
  export { AeonRouter } from './router.js';
26
26
  export { AeonRouteRegistry } from './registry';
27
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';
28
+ export type { NavigationOptions, PrefetchOptions, NavigationState, PresenceInfo as RoutePresenceInfo, } from './navigation';
29
+ export { NavigationCache, getNavigationCache, setNavigationCache, SkeletonCache, getSkeletonCache, setSkeletonCache, getWithSkeleton, } from './cache';
30
+ export type { CachedSession, CacheStats, NavigationCacheOptions, CachedSkeleton, SkeletonCacheOptions, SkeletonWithContent, } from './cache';
31
+ export { initSkeleton, swapToContent, isSkeletonVisible, generateSkeletonInitScript, generateSkeletonPageStructure, generateAsyncSwapScript, } from './skeleton-hydrate';
32
+ export type { SkeletonSwapOptions } from './skeleton-hydrate';
31
33
  export { NavigationPredictor, getPredictor, setPredictor, } from './predictor';
32
34
  export type { PredictedRoute, NavigationRecord, CommunityPattern, PredictorConfig, } from './predictor';
35
+ export { SpeculativeRenderer, getSpeculativeRenderer, setSpeculativeRenderer, initSpeculativeRendering, } from './speculation';
36
+ export type { PreRenderedPage, SpeculativeRendererConfig, } from './speculation';
33
37
  export { createStorageAdapter, FileStorageAdapter, D1StorageAdapter, DurableObjectStorageAdapter, HybridStorageAdapter, DashStorageAdapter, } from './storage';
34
38
  export type { StorageAdapter } from './storage';
35
39
  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';
40
+ export { ApiRouter, createApiRouter, json, redirect, error, notFound, badRequest, unauthorized, forbidden, composeMiddleware, cors, requireAuth, rateLimit, } from './api-routes';
41
+ export type { Middleware } from './api-routes';
42
+ export { createAeonWorker } from './worker';
43
+ export type { AeonWorkerOptions } from './worker';
44
+ export { adaptRequest, adaptHandler, adaptRouteModule, NextResponse, } from './nextjs-adapter';
45
+ export type { NextRequest, NextRouteHandler, NextRouteModule, } from './nextjs-adapter';
46
+ export type { OperationType, OperationPriority, OperationStatus, OfflineOperation, EncryptedQueueConfig, QueueStats, EncryptedPayload, EncryptionKeyMaterial, SyncBatch, SyncResult, ConflictDetectionResult, ResolutionStrategy, StoredConflict, NetworkState, BandwidthProfile, NetworkStateEvent, SyncCoordinatorConfig, SyncProgressEvent, OfflineQueueEvents, SyncCoordinatorEvents, } from './offline/types';
47
+ export { OfflineOperationEncryption, getOperationEncryption, resetOperationEncryption, generateOperationId, estimateEncryptedSize, } from './offline/encryption';
48
+ export { EncryptedOfflineQueue, getOfflineQueue, createOfflineQueue, resetOfflineQueue, } from './offline/encrypted-queue';
49
+ export { ConflictResolver, getConflictResolver, createConflictResolver, resetConflictResolver, type ConflictResolverConfig, type ConflictStats as ConflictResolverStats, } from './sync/conflict-resolver';
50
+ export { SyncCoordinator, getSyncCoordinator, createSyncCoordinator, resetSyncCoordinator, type SyncStats, } from './sync/coordinator';
51
+ export { handlePush, handleNotificationClick, handleNotificationClose, handleSync, handleMessage, registerPushHandlers, registerSyncHandlers, registerMessageHandlers, urlBase64ToUint8Array, serializePushSubscription, type PushNotificationData, type PushHandlerConfig, type ServiceWorkerMessage, } from './service-worker-push';
52
+ export type { AeonConfig, AeonOptions, SyncOptions, VersioningOptions, PresenceOptions, OfflineOptions, PushOptions, InstallOptions, ComponentOptions, OutputOptions, RouteDefinition, RouteMatch, RouteMetadata, RouteOperation, SerializedComponent, PageSession, PresenceInfo, PresenceUser, AeonCapability, SkeletonShape, SkeletonSource, SkeletonDimensions, SkeletonMetadata, SkeletonHint, HttpMethod, AeonEnv, AeonContext, ExecutionContext, ApiRouteHandler, ApiRouteModule, ApiRoute, ApiRouteMatch, ApiRouteSegment, ServerRouteModule, ServerLoaderResult, ServerActionResult, D1Database, D1PreparedStatement, D1Result, D1ExecResult, KVNamespace, DurableObjectNamespace, DurableObjectId, DurableObjectStub, Ai, } from './types';
37
53
  export { DEFAULT_ROUTER_CONFIG, DEFAULT_ESI_CONFIG, HeuristicAdapter, EdgeWorkersESIProcessor, extractUserContext, createContextMiddleware, setContextCookies, addSpeculationHeaders, esiInfer, esiEmbed, esiEmotion, esiVision, esiWithContext, } from './router/index';
38
54
  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";
55
+ export declare const VERSION = "1.0.0";