@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,728 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aeon Pages Type Definitions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface AeonConfig {
|
|
6
|
+
/** Directory containing pages (default: './pages') */
|
|
7
|
+
pagesDir: string;
|
|
8
|
+
|
|
9
|
+
/** Directory containing components (default: './components') */
|
|
10
|
+
componentsDir?: string;
|
|
11
|
+
|
|
12
|
+
/** Runtime target: 'bun' or 'cloudflare' */
|
|
13
|
+
runtime: 'bun' | 'cloudflare';
|
|
14
|
+
|
|
15
|
+
/** Server port (default: 3000) */
|
|
16
|
+
port?: number;
|
|
17
|
+
|
|
18
|
+
/** Aeon-specific configuration */
|
|
19
|
+
aeon?: AeonOptions;
|
|
20
|
+
|
|
21
|
+
/** Component configuration */
|
|
22
|
+
components?: ComponentOptions;
|
|
23
|
+
|
|
24
|
+
/** Next.js compatibility mode */
|
|
25
|
+
nextCompat?: boolean;
|
|
26
|
+
|
|
27
|
+
/** Build output configuration */
|
|
28
|
+
output?: OutputOptions;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface AeonOptions {
|
|
32
|
+
/** Distributed sync configuration */
|
|
33
|
+
sync?: SyncOptions;
|
|
34
|
+
|
|
35
|
+
/** Schema versioning configuration */
|
|
36
|
+
versioning?: VersioningOptions;
|
|
37
|
+
|
|
38
|
+
/** Presence tracking configuration */
|
|
39
|
+
presence?: PresenceOptions;
|
|
40
|
+
|
|
41
|
+
/** Offline support configuration */
|
|
42
|
+
offline?: OfflineOptions;
|
|
43
|
+
|
|
44
|
+
/** Push notification configuration */
|
|
45
|
+
push?: PushOptions;
|
|
46
|
+
|
|
47
|
+
/** PWA install prompt configuration */
|
|
48
|
+
install?: InstallOptions;
|
|
49
|
+
|
|
50
|
+
/** Allow dynamic route creation for unclaimed paths */
|
|
51
|
+
dynamicRoutes?: boolean;
|
|
52
|
+
|
|
53
|
+
/** Zero-CLS Skeleton configuration */
|
|
54
|
+
skeleton?: SkeletonOptions;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface SkeletonOptions {
|
|
58
|
+
/** Enable automatic skeleton generation */
|
|
59
|
+
enabled: boolean;
|
|
60
|
+
|
|
61
|
+
/** Minimum confidence to generate skeletons (0-1) */
|
|
62
|
+
minConfidence?: number;
|
|
63
|
+
|
|
64
|
+
/** Enable fade animation when swapping content */
|
|
65
|
+
fadeAnimation?: boolean;
|
|
66
|
+
|
|
67
|
+
/** Fade animation duration in ms */
|
|
68
|
+
fadeDuration?: number;
|
|
69
|
+
|
|
70
|
+
/** Components that always need skeletons (dynamic content) */
|
|
71
|
+
alwaysDynamic?: string[];
|
|
72
|
+
|
|
73
|
+
/** Components that never need skeletons (static containers) */
|
|
74
|
+
neverDynamic?: string[];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface SyncOptions {
|
|
78
|
+
/** Sync mode: 'distributed' for multi-node, 'local' for single-node */
|
|
79
|
+
mode: 'distributed' | 'local';
|
|
80
|
+
|
|
81
|
+
/** Number of replicas for distributed mode */
|
|
82
|
+
replicationFactor?: number;
|
|
83
|
+
|
|
84
|
+
/** Consistency level for reads/writes */
|
|
85
|
+
consistencyLevel?: 'strong' | 'eventual' | 'read-after-write';
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface VersioningOptions {
|
|
89
|
+
/** Enable schema versioning */
|
|
90
|
+
enabled: boolean;
|
|
91
|
+
|
|
92
|
+
/** Automatically run migrations */
|
|
93
|
+
autoMigrate?: boolean;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface PresenceOptions {
|
|
97
|
+
/** Enable presence tracking */
|
|
98
|
+
enabled: boolean;
|
|
99
|
+
|
|
100
|
+
/** Track cursor positions */
|
|
101
|
+
cursorTracking?: boolean;
|
|
102
|
+
|
|
103
|
+
/** Inactivity timeout in milliseconds */
|
|
104
|
+
inactivityTimeout?: number;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface OfflineOptions {
|
|
108
|
+
/** Enable offline support */
|
|
109
|
+
enabled: boolean;
|
|
110
|
+
|
|
111
|
+
/** Maximum operations to queue offline (default: 1000) */
|
|
112
|
+
maxQueueSize?: number;
|
|
113
|
+
|
|
114
|
+
/** Encryption configuration for offline queue */
|
|
115
|
+
encryption?: {
|
|
116
|
+
/** Enable encryption for queued operations */
|
|
117
|
+
enabled: boolean;
|
|
118
|
+
/** Key derivation method: 'ucan' for UCAN-derived keys, 'session' for session-based */
|
|
119
|
+
keyDerivation?: 'ucan' | 'session';
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/** Sync configuration */
|
|
123
|
+
sync?: {
|
|
124
|
+
/** Maximum operations per batch (default: 100) */
|
|
125
|
+
maxBatchSize?: number;
|
|
126
|
+
/** Maximum bytes per batch (default: 5MB) */
|
|
127
|
+
maxBatchBytes?: number;
|
|
128
|
+
/** Batch timeout in ms (default: 5000) */
|
|
129
|
+
batchTimeoutMs?: number;
|
|
130
|
+
/** Enable compression for batches (default: true) */
|
|
131
|
+
enableCompression?: boolean;
|
|
132
|
+
/** Enable delta sync (default: true) */
|
|
133
|
+
enableDeltaSync?: boolean;
|
|
134
|
+
/** Enable adaptive batch sizing based on network (default: true) */
|
|
135
|
+
adaptiveBatching?: boolean;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
/** Storage configuration */
|
|
139
|
+
storage?: {
|
|
140
|
+
/** Maximum local storage capacity in bytes (default: 50MB) */
|
|
141
|
+
maxLocalCapacity?: number;
|
|
142
|
+
/** Interval for D1 sync in ms (default: 5 minutes) */
|
|
143
|
+
d1SyncInterval?: number;
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** Push notification configuration */
|
|
148
|
+
export interface PushOptions {
|
|
149
|
+
/** Enable push notifications */
|
|
150
|
+
enabled: boolean;
|
|
151
|
+
|
|
152
|
+
/** VAPID public key for push subscription */
|
|
153
|
+
vapidPublicKey?: string;
|
|
154
|
+
|
|
155
|
+
/** Default notification icon */
|
|
156
|
+
defaultIcon?: string;
|
|
157
|
+
|
|
158
|
+
/** Default notification badge */
|
|
159
|
+
defaultBadge?: string;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** PWA install prompt configuration */
|
|
163
|
+
export interface InstallOptions {
|
|
164
|
+
/** Show install prompt when available */
|
|
165
|
+
showPrompt: boolean;
|
|
166
|
+
|
|
167
|
+
/** Show iOS-specific installation instructions */
|
|
168
|
+
iosInstructions: boolean;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export interface ComponentOptions {
|
|
172
|
+
/** Auto-discover components from componentsDir */
|
|
173
|
+
autoDiscover?: boolean;
|
|
174
|
+
|
|
175
|
+
/** Explicit list of components to include */
|
|
176
|
+
include?: string[];
|
|
177
|
+
|
|
178
|
+
/** Components to exclude from auto-discovery */
|
|
179
|
+
exclude?: string[];
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export interface OutputOptions {
|
|
183
|
+
/** Output directory for built assets */
|
|
184
|
+
dir?: string;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** Route definition */
|
|
188
|
+
export interface RouteDefinition {
|
|
189
|
+
/** Pattern like "/blog/[slug]" */
|
|
190
|
+
pattern: string;
|
|
191
|
+
|
|
192
|
+
/** Session ID template */
|
|
193
|
+
sessionId: string;
|
|
194
|
+
|
|
195
|
+
/** Component ID */
|
|
196
|
+
componentId: string;
|
|
197
|
+
|
|
198
|
+
/** Layout wrapper */
|
|
199
|
+
layout?: string;
|
|
200
|
+
|
|
201
|
+
/** Whether this route uses 'use aeon' */
|
|
202
|
+
isAeon: boolean;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** Route match result */
|
|
206
|
+
export interface RouteMatch {
|
|
207
|
+
/** The matched route */
|
|
208
|
+
route: RouteDefinition;
|
|
209
|
+
|
|
210
|
+
/** Extracted parameters */
|
|
211
|
+
params: Record<string, string>;
|
|
212
|
+
|
|
213
|
+
/** Resolved session ID */
|
|
214
|
+
sessionId: string;
|
|
215
|
+
|
|
216
|
+
/** Component ID shorthand */
|
|
217
|
+
componentId: string;
|
|
218
|
+
|
|
219
|
+
/** Is this an Aeon page? */
|
|
220
|
+
isAeon: boolean;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/** Route metadata for registry */
|
|
224
|
+
export interface RouteMetadata {
|
|
225
|
+
createdAt: string;
|
|
226
|
+
createdBy: string;
|
|
227
|
+
updatedAt?: string;
|
|
228
|
+
updatedBy?: string;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** Route operation for sync */
|
|
232
|
+
export interface RouteOperation {
|
|
233
|
+
type: 'route-add' | 'route-update' | 'route-remove';
|
|
234
|
+
path: string;
|
|
235
|
+
component?: string;
|
|
236
|
+
metadata?: RouteMetadata;
|
|
237
|
+
timestamp: string;
|
|
238
|
+
nodeId: string;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// =============================================================================
|
|
242
|
+
// SKELETON SYSTEM - Automatic skeleton generation for zero CLS
|
|
243
|
+
// =============================================================================
|
|
244
|
+
|
|
245
|
+
/** Shape types for skeleton rendering */
|
|
246
|
+
export type SkeletonShape =
|
|
247
|
+
| 'rect'
|
|
248
|
+
| 'circle'
|
|
249
|
+
| 'text-line'
|
|
250
|
+
| 'text-block'
|
|
251
|
+
| 'container';
|
|
252
|
+
|
|
253
|
+
/** Source of skeleton inference */
|
|
254
|
+
export type SkeletonSource = 'tailwind' | 'prop-defaults' | 'hint' | 'measured';
|
|
255
|
+
|
|
256
|
+
/** Skeleton dimensions extracted from Tailwind classes or props */
|
|
257
|
+
export interface SkeletonDimensions {
|
|
258
|
+
/** Width CSS value: '256px', '100%', 'auto' */
|
|
259
|
+
width?: string;
|
|
260
|
+
/** Height CSS value: '48px', 'auto' */
|
|
261
|
+
height?: string;
|
|
262
|
+
/** Min height CSS value */
|
|
263
|
+
minHeight?: string;
|
|
264
|
+
/** Aspect ratio: '16/9', '1/1' */
|
|
265
|
+
aspectRatio?: string;
|
|
266
|
+
/** Padding CSS value */
|
|
267
|
+
padding?: string;
|
|
268
|
+
/** Margin CSS value */
|
|
269
|
+
margin?: string;
|
|
270
|
+
/** Border radius CSS value */
|
|
271
|
+
borderRadius?: string;
|
|
272
|
+
/** Gap for flex/grid containers */
|
|
273
|
+
gap?: string;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/** Skeleton metadata attached to component nodes */
|
|
277
|
+
export interface SkeletonMetadata {
|
|
278
|
+
/** Computed dimensions from Tailwind/props/hints */
|
|
279
|
+
dimensions: SkeletonDimensions;
|
|
280
|
+
/** Shape hint for skeleton rendering */
|
|
281
|
+
shape: SkeletonShape;
|
|
282
|
+
/** Number of skeleton lines for text-block shape */
|
|
283
|
+
lines?: number;
|
|
284
|
+
/** Whether this node has dynamic content that needs skeleton */
|
|
285
|
+
isDynamic: boolean;
|
|
286
|
+
/** Confidence score (0-1) for inferred dimensions */
|
|
287
|
+
confidence: number;
|
|
288
|
+
/** Source of skeleton data */
|
|
289
|
+
source: SkeletonSource;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/** Skeleton hint parsed from data-skeleton-* attributes */
|
|
293
|
+
export interface SkeletonHint {
|
|
294
|
+
/** Explicit shape override */
|
|
295
|
+
shape?: SkeletonShape;
|
|
296
|
+
/** Explicit width override */
|
|
297
|
+
width?: string;
|
|
298
|
+
/** Explicit height override */
|
|
299
|
+
height?: string;
|
|
300
|
+
/** Number of lines for text-block */
|
|
301
|
+
lines?: number;
|
|
302
|
+
/** Skip skeleton generation for this element */
|
|
303
|
+
ignore?: boolean;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/** Serialized component tree */
|
|
307
|
+
export interface SerializedComponent {
|
|
308
|
+
type: string;
|
|
309
|
+
props?: Record<string, unknown>;
|
|
310
|
+
children?: (SerializedComponent | string)[];
|
|
311
|
+
/** Skeleton metadata for zero-CLS rendering (computed at build time) */
|
|
312
|
+
_skeleton?: SkeletonMetadata;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/** Page session stored in Aeon */
|
|
316
|
+
export interface PageSession {
|
|
317
|
+
/** Route this session serves */
|
|
318
|
+
route: string;
|
|
319
|
+
|
|
320
|
+
/** Current component state */
|
|
321
|
+
tree: SerializedComponent;
|
|
322
|
+
|
|
323
|
+
/** Page data */
|
|
324
|
+
data: Record<string, unknown>;
|
|
325
|
+
|
|
326
|
+
/** Schema version */
|
|
327
|
+
schema: { version: string };
|
|
328
|
+
|
|
329
|
+
/** Active presence info */
|
|
330
|
+
presence: PresenceInfo[];
|
|
331
|
+
|
|
332
|
+
/** Session version number (increments on each edit) */
|
|
333
|
+
version?: number;
|
|
334
|
+
|
|
335
|
+
/** Last modified timestamp */
|
|
336
|
+
updatedAt?: string;
|
|
337
|
+
|
|
338
|
+
/** Last modified by user/agent ID */
|
|
339
|
+
updatedBy?: string;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/** Webhook configuration for sync callbacks */
|
|
343
|
+
export interface WebhookConfig {
|
|
344
|
+
/** URL to call when session changes */
|
|
345
|
+
url: string;
|
|
346
|
+
|
|
347
|
+
/** Secret for HMAC signature verification */
|
|
348
|
+
secret?: string;
|
|
349
|
+
|
|
350
|
+
/** Events to trigger webhook: 'edit', 'publish', 'all' */
|
|
351
|
+
events: ('edit' | 'publish' | 'merge' | 'all')[];
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/** Webhook payload sent to callback URLs */
|
|
355
|
+
export interface WebhookPayload {
|
|
356
|
+
/** Event type */
|
|
357
|
+
event:
|
|
358
|
+
| 'session.updated'
|
|
359
|
+
| 'session.published'
|
|
360
|
+
| 'session.merged'
|
|
361
|
+
| 'github.push';
|
|
362
|
+
|
|
363
|
+
/** Session ID */
|
|
364
|
+
sessionId: string;
|
|
365
|
+
|
|
366
|
+
/** Route */
|
|
367
|
+
route: string;
|
|
368
|
+
|
|
369
|
+
/** Session version */
|
|
370
|
+
version: number;
|
|
371
|
+
|
|
372
|
+
/** Timestamp */
|
|
373
|
+
timestamp: string;
|
|
374
|
+
|
|
375
|
+
/** GitHub PR number (for publish/merge events) */
|
|
376
|
+
prNumber?: number;
|
|
377
|
+
|
|
378
|
+
/** User who triggered the event */
|
|
379
|
+
triggeredBy?: string;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/** Presence info for a user/agent */
|
|
383
|
+
export interface PresenceInfo {
|
|
384
|
+
/** User or agent ID */
|
|
385
|
+
userId: string;
|
|
386
|
+
|
|
387
|
+
/** User or agent role */
|
|
388
|
+
role: 'user' | 'assistant' | 'monitor' | 'admin';
|
|
389
|
+
|
|
390
|
+
/** Cursor position */
|
|
391
|
+
cursor?: { x: number; y: number };
|
|
392
|
+
|
|
393
|
+
/** Currently editing element path */
|
|
394
|
+
editing?: string;
|
|
395
|
+
|
|
396
|
+
/** Online/away/offline status */
|
|
397
|
+
status: 'online' | 'away' | 'offline';
|
|
398
|
+
|
|
399
|
+
/** Last activity timestamp */
|
|
400
|
+
lastActivity: string;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// =============================================================================
|
|
404
|
+
// UCAN CAPABILITIES - Authorization for Aeon pages and nodes
|
|
405
|
+
// =============================================================================
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Base capability actions for Aeon pages
|
|
409
|
+
* - aeon:read - Read access to page/node
|
|
410
|
+
* - aeon:write - Write access to page/node
|
|
411
|
+
* - aeon:admin - Full admin access (bypasses all restrictions)
|
|
412
|
+
* - aeon:* - Wildcard (all permissions)
|
|
413
|
+
*/
|
|
414
|
+
export type AeonCapabilityAction =
|
|
415
|
+
| 'aeon:read'
|
|
416
|
+
| 'aeon:write'
|
|
417
|
+
| 'aeon:admin'
|
|
418
|
+
| 'aeon:*';
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Node-level capability actions (Merkle hash-based)
|
|
422
|
+
* - aeon:node:read - Read access to specific node by Merkle hash
|
|
423
|
+
* - aeon:node:write - Write access to specific node by Merkle hash
|
|
424
|
+
* - aeon:node:* - All permissions on specific node
|
|
425
|
+
*/
|
|
426
|
+
export type AeonNodeCapabilityAction =
|
|
427
|
+
| 'aeon:node:read'
|
|
428
|
+
| 'aeon:node:write'
|
|
429
|
+
| 'aeon:node:*';
|
|
430
|
+
|
|
431
|
+
/** All capability action types */
|
|
432
|
+
export type AeonCapabilityActionType =
|
|
433
|
+
| AeonCapabilityAction
|
|
434
|
+
| AeonNodeCapabilityAction;
|
|
435
|
+
|
|
436
|
+
/** UCAN capability for Aeon pages */
|
|
437
|
+
export interface AeonCapability {
|
|
438
|
+
can: AeonCapabilityAction;
|
|
439
|
+
with: string;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* UCAN capability for node-level access (Merkle hash-based)
|
|
444
|
+
*
|
|
445
|
+
* @example
|
|
446
|
+
* ```ts
|
|
447
|
+
* // Grant read access to a specific node by Merkle hash
|
|
448
|
+
* const capability: AeonNodeCapability = {
|
|
449
|
+
* can: 'aeon:node:read',
|
|
450
|
+
* with: 'merkle:a1b2c3d4e5f6',
|
|
451
|
+
* };
|
|
452
|
+
*
|
|
453
|
+
* // Grant write access to all nodes under a path
|
|
454
|
+
* const pathCapability: AeonNodeCapability = {
|
|
455
|
+
* can: 'aeon:node:write',
|
|
456
|
+
* with: 'path:/dashboard/*',
|
|
457
|
+
* };
|
|
458
|
+
*
|
|
459
|
+
* // Grant access to node and all children (tree access)
|
|
460
|
+
* const treeCapability: AeonNodeCapability = {
|
|
461
|
+
* can: 'aeon:node:*',
|
|
462
|
+
* with: 'tree:a1b2c3d4e5f6',
|
|
463
|
+
* };
|
|
464
|
+
* ```
|
|
465
|
+
*/
|
|
466
|
+
export interface AeonNodeCapability {
|
|
467
|
+
can: AeonNodeCapabilityAction;
|
|
468
|
+
/**
|
|
469
|
+
* Resource identifier. Supports:
|
|
470
|
+
* - `merkle:<hash>` - Specific node by Merkle hash
|
|
471
|
+
* - `tree:<hash>` - Node and all descendants
|
|
472
|
+
* - `path:<route>` - All nodes on a route (supports wildcards)
|
|
473
|
+
* - `*` - All nodes (wildcard)
|
|
474
|
+
*/
|
|
475
|
+
with: string;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/** Combined capability type (page or node level) */
|
|
479
|
+
export type AeonAnyCapability = AeonCapability | AeonNodeCapability;
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Resource type for capability matching
|
|
483
|
+
*/
|
|
484
|
+
export type AeonResourceType = 'merkle' | 'tree' | 'path' | 'wildcard';
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Parsed resource identifier from capability
|
|
488
|
+
*/
|
|
489
|
+
export interface ParsedResource {
|
|
490
|
+
type: AeonResourceType;
|
|
491
|
+
value: string;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* Merkle node access request
|
|
496
|
+
* Used when verifying access to a specific node
|
|
497
|
+
*/
|
|
498
|
+
export interface MerkleAccessRequest {
|
|
499
|
+
/** The Merkle hash of the node */
|
|
500
|
+
merkleHash: string;
|
|
501
|
+
/** Full tree path from root to node */
|
|
502
|
+
treePath?: string[];
|
|
503
|
+
/** Merkle hashes of ancestors (for tree-based checks) */
|
|
504
|
+
ancestorHashes?: string[];
|
|
505
|
+
/** The route/page path */
|
|
506
|
+
routePath?: string;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/** Alias for PresenceInfo - used by react package */
|
|
510
|
+
export type PresenceUser = PresenceInfo;
|
|
511
|
+
|
|
512
|
+
// =============================================================================
|
|
513
|
+
// API ROUTES - Server-side request handling
|
|
514
|
+
// =============================================================================
|
|
515
|
+
|
|
516
|
+
/** HTTP methods supported for API routes */
|
|
517
|
+
export type HttpMethod =
|
|
518
|
+
| 'GET'
|
|
519
|
+
| 'POST'
|
|
520
|
+
| 'PUT'
|
|
521
|
+
| 'PATCH'
|
|
522
|
+
| 'DELETE'
|
|
523
|
+
| 'HEAD'
|
|
524
|
+
| 'OPTIONS';
|
|
525
|
+
|
|
526
|
+
/** Cloudflare Workers environment bindings */
|
|
527
|
+
export interface AeonEnv {
|
|
528
|
+
/** Durable Object namespace for page sessions */
|
|
529
|
+
PAGE_SESSIONS?: DurableObjectNamespace;
|
|
530
|
+
/** Durable Object namespace for routes registry */
|
|
531
|
+
ROUTES_REGISTRY?: DurableObjectNamespace;
|
|
532
|
+
/** D1 Database binding */
|
|
533
|
+
DB?: D1Database;
|
|
534
|
+
/** Workers KV namespace for caching */
|
|
535
|
+
CACHE?: KVNamespace;
|
|
536
|
+
/** Workers AI binding */
|
|
537
|
+
AI?: Ai;
|
|
538
|
+
/** Environment name (development, staging, production) */
|
|
539
|
+
ENVIRONMENT?: string;
|
|
540
|
+
/** Allow additional custom bindings */
|
|
541
|
+
[key: string]: unknown;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/** D1 Database interface */
|
|
545
|
+
export interface D1Database {
|
|
546
|
+
prepare(query: string): D1PreparedStatement;
|
|
547
|
+
exec(query: string): Promise<D1ExecResult>;
|
|
548
|
+
batch<T = unknown>(statements: D1PreparedStatement[]): Promise<D1Result<T>[]>;
|
|
549
|
+
dump(): Promise<ArrayBuffer>;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
export interface D1PreparedStatement {
|
|
553
|
+
bind(...values: unknown[]): D1PreparedStatement;
|
|
554
|
+
run(): Promise<D1Result>;
|
|
555
|
+
first<T = unknown>(colName?: string): Promise<T | null>;
|
|
556
|
+
all<T = unknown>(): Promise<D1Result<T>>;
|
|
557
|
+
raw<T = unknown>(): Promise<T[]>;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
export interface D1Result<T = unknown> {
|
|
561
|
+
results?: T[];
|
|
562
|
+
success: boolean;
|
|
563
|
+
error?: string;
|
|
564
|
+
meta?: {
|
|
565
|
+
duration: number;
|
|
566
|
+
changes: number;
|
|
567
|
+
last_row_id: number;
|
|
568
|
+
served_by: string;
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
export interface D1ExecResult {
|
|
573
|
+
count: number;
|
|
574
|
+
duration: number;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/** KV Namespace interface */
|
|
578
|
+
export interface KVNamespace {
|
|
579
|
+
get(
|
|
580
|
+
key: string,
|
|
581
|
+
options?: { type?: 'text' | 'json' | 'arrayBuffer' | 'stream' },
|
|
582
|
+
): Promise<string | null>;
|
|
583
|
+
getWithMetadata<T = unknown>(
|
|
584
|
+
key: string,
|
|
585
|
+
): Promise<{ value: string | null; metadata: T | null }>;
|
|
586
|
+
put(
|
|
587
|
+
key: string,
|
|
588
|
+
value: string | ArrayBuffer | ReadableStream,
|
|
589
|
+
options?: { expirationTtl?: number; metadata?: unknown },
|
|
590
|
+
): Promise<void>;
|
|
591
|
+
delete(key: string): Promise<void>;
|
|
592
|
+
list(options?: {
|
|
593
|
+
prefix?: string;
|
|
594
|
+
limit?: number;
|
|
595
|
+
cursor?: string;
|
|
596
|
+
}): Promise<{
|
|
597
|
+
keys: { name: string }[];
|
|
598
|
+
list_complete: boolean;
|
|
599
|
+
cursor?: string;
|
|
600
|
+
}>;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/** Durable Object Namespace interface */
|
|
604
|
+
export interface DurableObjectNamespace {
|
|
605
|
+
idFromName(name: string): DurableObjectId;
|
|
606
|
+
idFromString(id: string): DurableObjectId;
|
|
607
|
+
newUniqueId(): DurableObjectId;
|
|
608
|
+
get(id: DurableObjectId): DurableObjectStub;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
export interface DurableObjectId {
|
|
612
|
+
toString(): string;
|
|
613
|
+
equals(other: DurableObjectId): boolean;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
export interface DurableObjectStub {
|
|
617
|
+
fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
|
618
|
+
id: DurableObjectId;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/** Workers AI interface */
|
|
622
|
+
export interface Ai {
|
|
623
|
+
run<T = unknown>(
|
|
624
|
+
model: string,
|
|
625
|
+
inputs: unknown,
|
|
626
|
+
options?: { gateway?: { id: string } },
|
|
627
|
+
): Promise<T>;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/** Context passed to API route handlers */
|
|
631
|
+
export interface AeonContext<E extends AeonEnv = AeonEnv> {
|
|
632
|
+
/** The incoming request */
|
|
633
|
+
request: Request;
|
|
634
|
+
/** Environment bindings (D1, KV, AI, Durable Objects, etc.) */
|
|
635
|
+
env: E;
|
|
636
|
+
/** Extracted URL parameters from dynamic routes */
|
|
637
|
+
params: Record<string, string>;
|
|
638
|
+
/** The request URL parsed */
|
|
639
|
+
url: URL;
|
|
640
|
+
/** Execution context for waitUntil, etc. */
|
|
641
|
+
ctx: ExecutionContext;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/** Execution context for Cloudflare Workers */
|
|
645
|
+
export interface ExecutionContext {
|
|
646
|
+
waitUntil(promise: Promise<unknown>): void;
|
|
647
|
+
passThroughOnException(): void;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/** API route handler function */
|
|
651
|
+
export type ApiRouteHandler<E extends AeonEnv = AeonEnv> = (
|
|
652
|
+
context: AeonContext<E>,
|
|
653
|
+
) => Response | Promise<Response>;
|
|
654
|
+
|
|
655
|
+
/** API route module - exports handlers for each HTTP method */
|
|
656
|
+
export interface ApiRouteModule<E extends AeonEnv = AeonEnv> {
|
|
657
|
+
GET?: ApiRouteHandler<E>;
|
|
658
|
+
POST?: ApiRouteHandler<E>;
|
|
659
|
+
PUT?: ApiRouteHandler<E>;
|
|
660
|
+
PATCH?: ApiRouteHandler<E>;
|
|
661
|
+
DELETE?: ApiRouteHandler<E>;
|
|
662
|
+
HEAD?: ApiRouteHandler<E>;
|
|
663
|
+
OPTIONS?: ApiRouteHandler<E>;
|
|
664
|
+
/** Catch-all handler for any method */
|
|
665
|
+
default?: ApiRouteHandler<E>;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/** Registered API route */
|
|
669
|
+
export interface ApiRoute {
|
|
670
|
+
/** Route pattern (e.g., "/api/chat", "/api/users/[id]") */
|
|
671
|
+
pattern: string;
|
|
672
|
+
/** Parsed path segments for matching */
|
|
673
|
+
segments: ApiRouteSegment[];
|
|
674
|
+
/** The route module with handlers */
|
|
675
|
+
module: ApiRouteModule;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/** Segment of an API route pattern */
|
|
679
|
+
export interface ApiRouteSegment {
|
|
680
|
+
/** The segment text */
|
|
681
|
+
value: string;
|
|
682
|
+
/** Is this a dynamic parameter? */
|
|
683
|
+
isDynamic: boolean;
|
|
684
|
+
/** Is this a catch-all segment? */
|
|
685
|
+
isCatchAll: boolean;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/** API route match result */
|
|
689
|
+
export interface ApiRouteMatch {
|
|
690
|
+
/** The matched route */
|
|
691
|
+
route: ApiRoute;
|
|
692
|
+
/** Extracted parameters */
|
|
693
|
+
params: Record<string, string>;
|
|
694
|
+
/** The handler for the request method */
|
|
695
|
+
handler: ApiRouteHandler;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/** Server route module - for page-level server logic */
|
|
699
|
+
export interface ServerRouteModule<E extends AeonEnv = AeonEnv> {
|
|
700
|
+
/** Called before page render - can return data or redirect */
|
|
701
|
+
loader?: (context: AeonContext<E>) => Promise<ServerLoaderResult>;
|
|
702
|
+
/** Called on form submission or POST to the page */
|
|
703
|
+
action?: (context: AeonContext<E>) => Promise<ServerActionResult>;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
/** Result from a server loader */
|
|
707
|
+
export interface ServerLoaderResult {
|
|
708
|
+
/** Data to pass to the page */
|
|
709
|
+
data?: Record<string, unknown>;
|
|
710
|
+
/** Redirect to another URL */
|
|
711
|
+
redirect?: string;
|
|
712
|
+
/** Response status code */
|
|
713
|
+
status?: number;
|
|
714
|
+
/** Additional headers */
|
|
715
|
+
headers?: Record<string, string>;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/** Result from a server action */
|
|
719
|
+
export interface ServerActionResult {
|
|
720
|
+
/** Data to return */
|
|
721
|
+
data?: Record<string, unknown>;
|
|
722
|
+
/** Errors to display */
|
|
723
|
+
errors?: Record<string, string>;
|
|
724
|
+
/** Redirect after action */
|
|
725
|
+
redirect?: string;
|
|
726
|
+
/** Response status code */
|
|
727
|
+
status?: number;
|
|
728
|
+
}
|