@almadar/runtime 1.0.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/LICENSE +72 -0
- package/dist/OrbitalServerRuntime-COj7K1yM.d.ts +736 -0
- package/dist/OrbitalServerRuntime.d.ts +4 -0
- package/dist/OrbitalServerRuntime.js +3185 -0
- package/dist/OrbitalServerRuntime.js.map +1 -0
- package/dist/ServerBridge.d.ts +118 -0
- package/dist/ServerBridge.js +242 -0
- package/dist/ServerBridge.js.map +1 -0
- package/dist/index.d.ts +291 -0
- package/dist/index.js +1556 -0
- package/dist/index.js.map +1 -0
- package/dist/types-JFCKD0FU.d.ts +175 -0
- package/package.json +65 -0
|
@@ -0,0 +1,736 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { I as IEventBus, R as RuntimeEvent, e as EventListener, U as Unsubscribe, E as EffectHandlers, d as Effect, T as TraitState } from './types-JFCKD0FU.js';
|
|
3
|
+
import { OrbitalSchema, Orbital, Trait } from '@almadar/core';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* EventBus - Platform-Agnostic Pub/Sub Implementation
|
|
7
|
+
*
|
|
8
|
+
* Pure TypeScript event bus for cross-trait communication.
|
|
9
|
+
* Works on both client (browser) and server (Node.js).
|
|
10
|
+
*
|
|
11
|
+
* @packageDocumentation
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* EventBus - Simple pub/sub event bus
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const bus = new EventBus({ debug: true });
|
|
20
|
+
*
|
|
21
|
+
* // Subscribe
|
|
22
|
+
* const unsub = bus.on('ORDER_CONFIRMED', (event) => {
|
|
23
|
+
* console.log('Order confirmed:', event.payload);
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* // Emit
|
|
27
|
+
* bus.emit('ORDER_CONFIRMED', { orderId: '123' });
|
|
28
|
+
*
|
|
29
|
+
* // Unsubscribe
|
|
30
|
+
* unsub();
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
declare class EventBus implements IEventBus {
|
|
34
|
+
private listeners;
|
|
35
|
+
private debug;
|
|
36
|
+
constructor(options?: {
|
|
37
|
+
debug?: boolean;
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* Emit an event to all registered listeners
|
|
41
|
+
*/
|
|
42
|
+
emit(type: string, payload?: Record<string, unknown>, source?: RuntimeEvent['source']): void;
|
|
43
|
+
/**
|
|
44
|
+
* Subscribe to an event type
|
|
45
|
+
*/
|
|
46
|
+
on(type: string, listener: EventListener): Unsubscribe;
|
|
47
|
+
/**
|
|
48
|
+
* Subscribe to ALL events (wildcard listener)
|
|
49
|
+
* Useful for event tracking, logging, debugging
|
|
50
|
+
*/
|
|
51
|
+
onAny(listener: EventListener): Unsubscribe;
|
|
52
|
+
/**
|
|
53
|
+
* Check if there are listeners for an event type
|
|
54
|
+
*/
|
|
55
|
+
hasListeners(type: string): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Get all registered event types
|
|
58
|
+
*/
|
|
59
|
+
getRegisteredEvents(): string[];
|
|
60
|
+
/**
|
|
61
|
+
* Clear all listeners
|
|
62
|
+
*/
|
|
63
|
+
clear(): void;
|
|
64
|
+
/**
|
|
65
|
+
* Get listener count for an event type (for testing)
|
|
66
|
+
*/
|
|
67
|
+
getListenerCount(type: string): number;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* External Orbital Loader
|
|
72
|
+
*
|
|
73
|
+
* Loads external .orb files from various sources:
|
|
74
|
+
* - Local filesystem (relative paths)
|
|
75
|
+
* - Standard library (std/...)
|
|
76
|
+
* - Scoped packages (@name/...)
|
|
77
|
+
*
|
|
78
|
+
* @packageDocumentation
|
|
79
|
+
*/
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Loader options.
|
|
83
|
+
*/
|
|
84
|
+
interface LoaderOptions {
|
|
85
|
+
/** Base directory for resolving relative imports */
|
|
86
|
+
basePath: string;
|
|
87
|
+
/** Standard library root path */
|
|
88
|
+
stdLibPath?: string;
|
|
89
|
+
/** Scoped package roots (e.g., { "@game-lib": "/path/to/lib" }) */
|
|
90
|
+
scopedPaths?: Record<string, string>;
|
|
91
|
+
/** Whether to allow paths outside basePath (security) */
|
|
92
|
+
allowOutsideBasePath?: boolean;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* SchemaLoader Interface
|
|
97
|
+
*
|
|
98
|
+
* Abstract interface for loading OrbitalSchema files from various sources.
|
|
99
|
+
* Implementations exist for:
|
|
100
|
+
* - FileSystemLoader (Node.js) - uses fs module
|
|
101
|
+
* - HttpLoader (Browser) - uses fetch API
|
|
102
|
+
* - UnifiedLoader (Auto-detect) - routes to appropriate loader
|
|
103
|
+
*
|
|
104
|
+
* @packageDocumentation
|
|
105
|
+
*/
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Result of loading a schema.
|
|
109
|
+
*/
|
|
110
|
+
interface LoadedSchema {
|
|
111
|
+
/** The loaded schema */
|
|
112
|
+
schema: OrbitalSchema;
|
|
113
|
+
/** Source path/URL (resolved) */
|
|
114
|
+
sourcePath: string;
|
|
115
|
+
/** Original import path */
|
|
116
|
+
importPath: string;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Result of loading a single orbital from a schema.
|
|
120
|
+
*/
|
|
121
|
+
interface LoadedOrbital {
|
|
122
|
+
/** The loaded orbital */
|
|
123
|
+
orbital: Orbital;
|
|
124
|
+
/** Source path/URL (resolved) */
|
|
125
|
+
sourcePath: string;
|
|
126
|
+
/** Original import path */
|
|
127
|
+
importPath: string;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Loader result with error handling.
|
|
131
|
+
*/
|
|
132
|
+
type LoadResult<T> = {
|
|
133
|
+
success: true;
|
|
134
|
+
data: T;
|
|
135
|
+
} | {
|
|
136
|
+
success: false;
|
|
137
|
+
error: string;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* Abstract interface for schema loaders.
|
|
141
|
+
*
|
|
142
|
+
* All loaders must implement:
|
|
143
|
+
* - load() - Load a schema from an import path
|
|
144
|
+
* - resolvePath() - Resolve an import path to absolute path/URL
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* // Using FileSystemLoader (Node.js)
|
|
149
|
+
* const loader: SchemaLoader = new FileSystemLoader({ basePath: "/schemas" });
|
|
150
|
+
* const result = await loader.load("./my-schema.orb");
|
|
151
|
+
*
|
|
152
|
+
* // Using HttpLoader (Browser)
|
|
153
|
+
* const loader: SchemaLoader = new HttpLoader({ basePath: "/api/schemas" });
|
|
154
|
+
* const result = await loader.load("./my-schema.orb");
|
|
155
|
+
*
|
|
156
|
+
* // Using UnifiedLoader (auto-detect)
|
|
157
|
+
* const loader: SchemaLoader = createUnifiedLoader({ basePath: "/schemas" });
|
|
158
|
+
* const result = await loader.load("./my-schema.orb");
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
interface SchemaLoader {
|
|
162
|
+
/**
|
|
163
|
+
* Load a schema from an import path.
|
|
164
|
+
*
|
|
165
|
+
* @param importPath - The import path (e.g., "./health.orb", "std/behaviors/game-core")
|
|
166
|
+
* @param fromPath - The path of the file doing the import (for relative resolution)
|
|
167
|
+
* @param chain - Import chain for circular detection (optional)
|
|
168
|
+
*/
|
|
169
|
+
load(importPath: string, fromPath?: string, chain?: ImportChainLike): Promise<LoadResult<LoadedSchema>>;
|
|
170
|
+
/**
|
|
171
|
+
* Load a specific orbital from a schema by name.
|
|
172
|
+
*
|
|
173
|
+
* @param importPath - The import path
|
|
174
|
+
* @param orbitalName - The orbital name (optional, defaults to first orbital)
|
|
175
|
+
* @param fromPath - The path of the file doing the import
|
|
176
|
+
* @param chain - Import chain for circular detection (optional)
|
|
177
|
+
*/
|
|
178
|
+
loadOrbital(importPath: string, orbitalName?: string, fromPath?: string, chain?: ImportChainLike): Promise<LoadResult<LoadedOrbital>>;
|
|
179
|
+
/**
|
|
180
|
+
* Resolve an import path to an absolute path/URL.
|
|
181
|
+
*
|
|
182
|
+
* @param importPath - The import path
|
|
183
|
+
* @param fromPath - The path of the file doing the import (optional)
|
|
184
|
+
*/
|
|
185
|
+
resolvePath(importPath: string, fromPath?: string): LoadResult<string>;
|
|
186
|
+
/**
|
|
187
|
+
* Clear the loader's cache.
|
|
188
|
+
*/
|
|
189
|
+
clearCache(): void;
|
|
190
|
+
/**
|
|
191
|
+
* Get cache statistics.
|
|
192
|
+
*/
|
|
193
|
+
getCacheStats(): {
|
|
194
|
+
size: number;
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Interface for import chain (circular detection).
|
|
199
|
+
* This allows different implementations to interoperate.
|
|
200
|
+
*/
|
|
201
|
+
interface ImportChainLike {
|
|
202
|
+
/**
|
|
203
|
+
* Try to add a path to the chain.
|
|
204
|
+
* @returns Error message if circular, null if OK
|
|
205
|
+
*/
|
|
206
|
+
push(absolutePath: string): string | null;
|
|
207
|
+
/**
|
|
208
|
+
* Remove the last path from the chain.
|
|
209
|
+
*/
|
|
210
|
+
pop(): void;
|
|
211
|
+
/**
|
|
212
|
+
* Clone the chain for nested loading.
|
|
213
|
+
*/
|
|
214
|
+
clone(): ImportChainLike;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Reference Resolver
|
|
219
|
+
*
|
|
220
|
+
* Resolves `uses` imports and component references in OrbitalSchema.
|
|
221
|
+
* Handles:
|
|
222
|
+
* - `Alias.entity` entity references
|
|
223
|
+
* - `Alias.traits.TraitName` trait references
|
|
224
|
+
* - `Alias.pages.PageName` page references
|
|
225
|
+
*
|
|
226
|
+
* @packageDocumentation
|
|
227
|
+
*/
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Resolution options.
|
|
231
|
+
*/
|
|
232
|
+
interface ResolveOptions extends LoaderOptions {
|
|
233
|
+
/** Map of local trait definitions (name -> trait) */
|
|
234
|
+
localTraits?: Map<string, Trait>;
|
|
235
|
+
/** Whether to skip loading external imports (for testing) */
|
|
236
|
+
skipExternalLoading?: boolean;
|
|
237
|
+
/** Custom schema loader instance (optional, defaults to ExternalOrbitalLoader) */
|
|
238
|
+
loader?: SchemaLoader;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Uses Integration for OrbitalServerRuntime
|
|
243
|
+
*
|
|
244
|
+
* Pre-processes OrbitalSchema to resolve `uses` declarations
|
|
245
|
+
* before registration with the runtime.
|
|
246
|
+
*
|
|
247
|
+
* Features:
|
|
248
|
+
* - Resolves all `uses` imports
|
|
249
|
+
* - Expands entity/trait/page references
|
|
250
|
+
* - Handles entity persistence semantics
|
|
251
|
+
* - Applies event namespacing for imported traits
|
|
252
|
+
*
|
|
253
|
+
* @packageDocumentation
|
|
254
|
+
*/
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Result of pre-processing a schema.
|
|
258
|
+
*/
|
|
259
|
+
interface PreprocessedSchema {
|
|
260
|
+
/** Schema with all references resolved */
|
|
261
|
+
schema: OrbitalSchema;
|
|
262
|
+
/** Entity sharing information (for runtime isolation) */
|
|
263
|
+
entitySharing: EntitySharingMap;
|
|
264
|
+
/** Event namespace mapping */
|
|
265
|
+
eventNamespaces: EventNamespaceMap;
|
|
266
|
+
/** Warnings from resolution */
|
|
267
|
+
warnings: string[];
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Map of orbital -> entity sharing info
|
|
271
|
+
*/
|
|
272
|
+
interface EntitySharingMap {
|
|
273
|
+
[orbitalName: string]: {
|
|
274
|
+
/** The entity name */
|
|
275
|
+
entityName: string;
|
|
276
|
+
/** Persistence type */
|
|
277
|
+
persistence: "persistent" | "runtime" | "singleton";
|
|
278
|
+
/** Whether this entity is shared with other orbitals */
|
|
279
|
+
isShared: boolean;
|
|
280
|
+
/** Source orbital if imported */
|
|
281
|
+
sourceAlias?: string;
|
|
282
|
+
/** Collection name for persistent entities */
|
|
283
|
+
collectionName?: string;
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Map of trait events to namespaced events
|
|
288
|
+
*/
|
|
289
|
+
interface EventNamespaceMap {
|
|
290
|
+
[orbitalName: string]: {
|
|
291
|
+
[traitName: string]: {
|
|
292
|
+
/** Original event -> namespaced event */
|
|
293
|
+
emits: Record<string, string>;
|
|
294
|
+
/** Namespaced event -> original event (for listeners) */
|
|
295
|
+
listens: Record<string, string>;
|
|
296
|
+
};
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Options for preprocessing.
|
|
301
|
+
*/
|
|
302
|
+
interface PreprocessOptions extends ResolveOptions {
|
|
303
|
+
/** Apply event namespacing to imported traits */
|
|
304
|
+
namespaceEvents?: boolean;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Result type for preprocessing.
|
|
308
|
+
*/
|
|
309
|
+
type PreprocessResult = {
|
|
310
|
+
success: true;
|
|
311
|
+
data: PreprocessedSchema;
|
|
312
|
+
} | {
|
|
313
|
+
success: false;
|
|
314
|
+
errors: string[];
|
|
315
|
+
};
|
|
316
|
+
/**
|
|
317
|
+
* Preprocess a schema to resolve all `uses` references.
|
|
318
|
+
*
|
|
319
|
+
* This is the integration point between the new `uses` system and the
|
|
320
|
+
* existing OrbitalServerRuntime. It:
|
|
321
|
+
*
|
|
322
|
+
* 1. Resolves all `uses` declarations
|
|
323
|
+
* 2. Expands entity references to inline definitions
|
|
324
|
+
* 3. Expands trait references to inline definitions
|
|
325
|
+
* 4. Expands page references with path overrides
|
|
326
|
+
* 5. Builds entity sharing map for runtime isolation
|
|
327
|
+
* 6. Builds event namespace map for cross-orbital events
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* ```typescript
|
|
331
|
+
* const result = await preprocessSchema(schema, {
|
|
332
|
+
* basePath: "/project/schemas",
|
|
333
|
+
* });
|
|
334
|
+
*
|
|
335
|
+
* if (result.success) {
|
|
336
|
+
* // Register the preprocessed schema
|
|
337
|
+
* runtime.register(result.data.schema);
|
|
338
|
+
*
|
|
339
|
+
* // Use entitySharing for isolation decisions
|
|
340
|
+
* if (result.data.entitySharing["Level1"].persistence === "runtime") {
|
|
341
|
+
* // Entities are isolated per orbital
|
|
342
|
+
* }
|
|
343
|
+
* }
|
|
344
|
+
* ```
|
|
345
|
+
*/
|
|
346
|
+
declare function preprocessSchema(schema: OrbitalSchema, options: PreprocessOptions): Promise<PreprocessResult>;
|
|
347
|
+
/**
|
|
348
|
+
* Get the collection name for an orbital's entity, considering isolation.
|
|
349
|
+
*
|
|
350
|
+
* - `persistent` entities share the same collection
|
|
351
|
+
* - `runtime` entities get isolated collections per orbital
|
|
352
|
+
* - `singleton` entities share a single-record collection
|
|
353
|
+
*/
|
|
354
|
+
declare function getIsolatedCollectionName(orbitalName: string, entitySharing: EntitySharingMap): string;
|
|
355
|
+
/**
|
|
356
|
+
* Get the namespaced event name for an orbital's trait event.
|
|
357
|
+
*/
|
|
358
|
+
declare function getNamespacedEvent(orbitalName: string, traitName: string, eventName: string, eventNamespaces: EventNamespaceMap): string;
|
|
359
|
+
/**
|
|
360
|
+
* Check if an event name is namespaced (contains dots).
|
|
361
|
+
*/
|
|
362
|
+
declare function isNamespacedEvent(eventName: string): boolean;
|
|
363
|
+
/**
|
|
364
|
+
* Parse a namespaced event name.
|
|
365
|
+
*/
|
|
366
|
+
declare function parseNamespacedEvent(eventName: string): {
|
|
367
|
+
orbital?: string;
|
|
368
|
+
trait?: string;
|
|
369
|
+
event: string;
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* OrbitalServerRuntime - Dynamic Server-Side Orbital Execution
|
|
374
|
+
*
|
|
375
|
+
* This runtime takes an OrbitalSchema and dynamically:
|
|
376
|
+
* 1. Registers all orbitals and their traits
|
|
377
|
+
* 2. Creates Express routes for trait communication
|
|
378
|
+
* 3. Executes state machines server-side
|
|
379
|
+
* 4. Handles cross-orbital event propagation
|
|
380
|
+
*
|
|
381
|
+
* This is the "interpreted" mode - no compilation needed.
|
|
382
|
+
* The compiler generates equivalent static code for production.
|
|
383
|
+
*
|
|
384
|
+
* @example
|
|
385
|
+
* ```typescript
|
|
386
|
+
* import { OrbitalServerRuntime } from '@kflow-builder/shared/runtime';
|
|
387
|
+
* import express from 'express';
|
|
388
|
+
*
|
|
389
|
+
* const app = express();
|
|
390
|
+
* const runtime = new OrbitalServerRuntime();
|
|
391
|
+
*
|
|
392
|
+
* // Register schema (can be loaded from file, API, etc.)
|
|
393
|
+
* runtime.register(orbitalSchema);
|
|
394
|
+
*
|
|
395
|
+
* // Mount orbital routes
|
|
396
|
+
* app.use('/api/orbitals', runtime.router());
|
|
397
|
+
*
|
|
398
|
+
* // Client can now:
|
|
399
|
+
* // POST /api/orbitals/:orbital/events - Send event to orbital
|
|
400
|
+
* // GET /api/orbitals/:orbital/state - Get current state
|
|
401
|
+
* // GET /api/orbitals - List registered orbitals
|
|
402
|
+
* ```
|
|
403
|
+
*
|
|
404
|
+
* @packageDocumentation
|
|
405
|
+
*/
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Simplified OrbitalSchema for runtime registration
|
|
409
|
+
* (Subset of full OrbitalSchema - just what's needed for execution)
|
|
410
|
+
*/
|
|
411
|
+
interface RuntimeOrbitalSchema {
|
|
412
|
+
name: string;
|
|
413
|
+
version?: string;
|
|
414
|
+
orbitals: RuntimeOrbital[];
|
|
415
|
+
}
|
|
416
|
+
interface RuntimeOrbital {
|
|
417
|
+
name: string;
|
|
418
|
+
entity: {
|
|
419
|
+
name: string;
|
|
420
|
+
fields?: Array<{
|
|
421
|
+
name: string;
|
|
422
|
+
type: string;
|
|
423
|
+
}>;
|
|
424
|
+
};
|
|
425
|
+
traits: RuntimeTrait[];
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Tick definition for scheduled effects
|
|
429
|
+
*/
|
|
430
|
+
interface RuntimeTraitTick {
|
|
431
|
+
/** Unique name for this tick */
|
|
432
|
+
name: string;
|
|
433
|
+
/** Interval in milliseconds, or cron expression string */
|
|
434
|
+
interval: number | string;
|
|
435
|
+
/** Guard condition (S-expression) - tick only executes if guard passes */
|
|
436
|
+
guard?: unknown;
|
|
437
|
+
/** Effects to execute when tick fires */
|
|
438
|
+
effects: Effect[];
|
|
439
|
+
/** Filter to specific entity IDs (optional) */
|
|
440
|
+
appliesTo?: string[];
|
|
441
|
+
}
|
|
442
|
+
interface RuntimeTrait {
|
|
443
|
+
name: string;
|
|
444
|
+
states: Array<{
|
|
445
|
+
name: string;
|
|
446
|
+
isInitial?: boolean;
|
|
447
|
+
}>;
|
|
448
|
+
transitions: Array<{
|
|
449
|
+
from: string;
|
|
450
|
+
to: string;
|
|
451
|
+
event: string;
|
|
452
|
+
guard?: unknown;
|
|
453
|
+
effects?: Effect[];
|
|
454
|
+
}>;
|
|
455
|
+
listens?: Array<{
|
|
456
|
+
event: string;
|
|
457
|
+
triggers: string;
|
|
458
|
+
payloadMapping?: Record<string, unknown>;
|
|
459
|
+
}>;
|
|
460
|
+
emits?: string[];
|
|
461
|
+
/** Scheduled ticks for this trait */
|
|
462
|
+
ticks?: RuntimeTraitTick[];
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Event sent from client to server
|
|
466
|
+
*/
|
|
467
|
+
interface OrbitalEventRequest {
|
|
468
|
+
event: string;
|
|
469
|
+
payload?: Record<string, unknown>;
|
|
470
|
+
entityId?: string;
|
|
471
|
+
/** User context for @user bindings (from Firebase auth) */
|
|
472
|
+
user?: {
|
|
473
|
+
uid: string;
|
|
474
|
+
email?: string;
|
|
475
|
+
displayName?: string;
|
|
476
|
+
[key: string]: unknown;
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Response from event processing
|
|
481
|
+
*/
|
|
482
|
+
interface OrbitalEventResponse {
|
|
483
|
+
success: boolean;
|
|
484
|
+
transitioned: boolean;
|
|
485
|
+
states: Record<string, string>;
|
|
486
|
+
emittedEvents: Array<{
|
|
487
|
+
event: string;
|
|
488
|
+
payload?: unknown;
|
|
489
|
+
}>;
|
|
490
|
+
/** Entity data fetched by `fetch` effects - keyed by entity type */
|
|
491
|
+
data?: Record<string, Record<string, unknown> | Record<string, unknown>[]>;
|
|
492
|
+
/** Client-side effects to execute (render-ui, navigate, notify) */
|
|
493
|
+
clientEffects?: Array<unknown>;
|
|
494
|
+
/** Results from server-side effects (persist, call-service, set) */
|
|
495
|
+
effectResults?: EffectResult[];
|
|
496
|
+
error?: string;
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Result of a server-side effect execution.
|
|
500
|
+
* Closes the circuit by returning effect outcomes to the client.
|
|
501
|
+
*/
|
|
502
|
+
interface EffectResult {
|
|
503
|
+
/** Effect type that was executed */
|
|
504
|
+
effect: 'persist' | 'call-service' | 'set';
|
|
505
|
+
/** Action performed (e.g., 'create', 'update', 'delete' for persist) */
|
|
506
|
+
action?: string;
|
|
507
|
+
/** Entity type affected (for persist/set) */
|
|
508
|
+
entityType?: string;
|
|
509
|
+
/** Result data from the effect */
|
|
510
|
+
data?: Record<string, unknown>;
|
|
511
|
+
/** Whether the effect succeeded */
|
|
512
|
+
success: boolean;
|
|
513
|
+
/** Error message if failed */
|
|
514
|
+
error?: string;
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Loader configuration for resolving `uses` imports
|
|
518
|
+
*/
|
|
519
|
+
interface LoaderConfig {
|
|
520
|
+
/** Base path for schema files */
|
|
521
|
+
basePath: string;
|
|
522
|
+
/** Standard library path (filesystem or URL) */
|
|
523
|
+
stdLibPath?: string;
|
|
524
|
+
/** Scoped package paths */
|
|
525
|
+
scopedPaths?: Record<string, string>;
|
|
526
|
+
/** Custom loader instance (overrides basePath/stdLibPath) */
|
|
527
|
+
loader?: SchemaLoader;
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Runtime configuration
|
|
531
|
+
*/
|
|
532
|
+
interface OrbitalServerRuntimeConfig {
|
|
533
|
+
/** Enable debug logging */
|
|
534
|
+
debug?: boolean;
|
|
535
|
+
/** Custom effect handlers (for integrating with your data layer) */
|
|
536
|
+
effectHandlers?: Partial<EffectHandlers>;
|
|
537
|
+
/** Persistence adapter for entity data */
|
|
538
|
+
persistence?: PersistenceAdapter;
|
|
539
|
+
/**
|
|
540
|
+
* Data mode:
|
|
541
|
+
* - 'mock': Use faker-generated mock data (default for preview)
|
|
542
|
+
* - 'real': Use actual persistence layer
|
|
543
|
+
*/
|
|
544
|
+
mode?: 'mock' | 'real';
|
|
545
|
+
/** Seed for deterministic mock data generation */
|
|
546
|
+
mockSeed?: number;
|
|
547
|
+
/** Number of mock records to generate per entity */
|
|
548
|
+
mockSeedCount?: number;
|
|
549
|
+
/**
|
|
550
|
+
* Loader configuration for resolving `uses` imports.
|
|
551
|
+
* Required when using `registerWithPreprocess` or `autoPreprocess`.
|
|
552
|
+
*/
|
|
553
|
+
loaderConfig?: LoaderConfig;
|
|
554
|
+
/**
|
|
555
|
+
* Automatically preprocess schemas on register() to resolve `uses` imports.
|
|
556
|
+
* Requires `loaderConfig` to be set.
|
|
557
|
+
* Default: false
|
|
558
|
+
*/
|
|
559
|
+
autoPreprocess?: boolean;
|
|
560
|
+
/**
|
|
561
|
+
* Apply event namespacing to imported traits.
|
|
562
|
+
* Default: true
|
|
563
|
+
*/
|
|
564
|
+
namespaceEvents?: boolean;
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Adapter for persisting entity data
|
|
568
|
+
*/
|
|
569
|
+
interface PersistenceAdapter {
|
|
570
|
+
create(entityType: string, data: Record<string, unknown>): Promise<{
|
|
571
|
+
id: string;
|
|
572
|
+
}>;
|
|
573
|
+
update(entityType: string, id: string, data: Record<string, unknown>): Promise<void>;
|
|
574
|
+
delete(entityType: string, id: string): Promise<void>;
|
|
575
|
+
getById(entityType: string, id: string): Promise<Record<string, unknown> | null>;
|
|
576
|
+
list(entityType: string): Promise<Array<Record<string, unknown>>>;
|
|
577
|
+
}
|
|
578
|
+
declare class OrbitalServerRuntime {
|
|
579
|
+
private orbitals;
|
|
580
|
+
private eventBus;
|
|
581
|
+
private config;
|
|
582
|
+
private persistence;
|
|
583
|
+
private listenerCleanups;
|
|
584
|
+
private tickBindings;
|
|
585
|
+
private loader;
|
|
586
|
+
private preprocessedCache;
|
|
587
|
+
private entitySharingMap;
|
|
588
|
+
private eventNamespaceMap;
|
|
589
|
+
constructor(config?: OrbitalServerRuntimeConfig);
|
|
590
|
+
/**
|
|
591
|
+
* Register an OrbitalSchema for execution.
|
|
592
|
+
*
|
|
593
|
+
* If `autoPreprocess` is enabled in config and schema has `uses` declarations,
|
|
594
|
+
* it will be preprocessed first to resolve imports.
|
|
595
|
+
*
|
|
596
|
+
* For explicit preprocessing control, use `registerWithPreprocess()`.
|
|
597
|
+
*/
|
|
598
|
+
register(schema: RuntimeOrbitalSchema): void;
|
|
599
|
+
/**
|
|
600
|
+
* Register an OrbitalSchema with preprocessing to resolve `uses` imports.
|
|
601
|
+
*
|
|
602
|
+
* This method:
|
|
603
|
+
* 1. Loads all external orbitals referenced in `uses` declarations
|
|
604
|
+
* 2. Expands entity/trait/page references to inline definitions
|
|
605
|
+
* 3. Builds entity sharing and event namespace maps
|
|
606
|
+
* 4. Caches the preprocessed result
|
|
607
|
+
* 5. Registers the resolved schema
|
|
608
|
+
*
|
|
609
|
+
* @param schema - Schema with potential `uses` declarations
|
|
610
|
+
* @param options - Optional preprocessing options
|
|
611
|
+
* @returns Preprocessing result with entity sharing info
|
|
612
|
+
*
|
|
613
|
+
* @example
|
|
614
|
+
* ```typescript
|
|
615
|
+
* const runtime = new OrbitalServerRuntime({
|
|
616
|
+
* loaderConfig: {
|
|
617
|
+
* basePath: '/schemas',
|
|
618
|
+
* stdLibPath: '/std',
|
|
619
|
+
* },
|
|
620
|
+
* });
|
|
621
|
+
*
|
|
622
|
+
* const result = await runtime.registerWithPreprocess(schema);
|
|
623
|
+
* if (result.success) {
|
|
624
|
+
* console.log('Registered with', Object.keys(result.entitySharing).length, 'orbitals');
|
|
625
|
+
* }
|
|
626
|
+
* ```
|
|
627
|
+
*/
|
|
628
|
+
registerWithPreprocess(schema: RuntimeOrbitalSchema, options?: {
|
|
629
|
+
sourcePath?: string;
|
|
630
|
+
}): Promise<{
|
|
631
|
+
success: boolean;
|
|
632
|
+
entitySharing?: EntitySharingMap;
|
|
633
|
+
eventNamespaces?: EventNamespaceMap;
|
|
634
|
+
warnings?: string[];
|
|
635
|
+
errors?: string[];
|
|
636
|
+
}>;
|
|
637
|
+
/**
|
|
638
|
+
* Get entity sharing information for registered orbitals.
|
|
639
|
+
* Useful for determining entity isolation and collection names.
|
|
640
|
+
*/
|
|
641
|
+
getEntitySharing(): EntitySharingMap;
|
|
642
|
+
/**
|
|
643
|
+
* Get event namespace mapping for registered orbitals.
|
|
644
|
+
* Useful for debugging cross-orbital event routing.
|
|
645
|
+
*/
|
|
646
|
+
getEventNamespaces(): EventNamespaceMap;
|
|
647
|
+
/**
|
|
648
|
+
* Clear the preprocessing cache.
|
|
649
|
+
*/
|
|
650
|
+
clearPreprocessCache(): void;
|
|
651
|
+
/**
|
|
652
|
+
* Register a single orbital
|
|
653
|
+
*/
|
|
654
|
+
private registerOrbital;
|
|
655
|
+
/**
|
|
656
|
+
* Set up event listeners for cross-orbital communication
|
|
657
|
+
*/
|
|
658
|
+
private setupEventListeners;
|
|
659
|
+
/**
|
|
660
|
+
* Set up scheduled ticks for all traits
|
|
661
|
+
*/
|
|
662
|
+
private setupTicks;
|
|
663
|
+
/**
|
|
664
|
+
* Register a single tick
|
|
665
|
+
*/
|
|
666
|
+
private registerTick;
|
|
667
|
+
/**
|
|
668
|
+
* Parse interval string to milliseconds
|
|
669
|
+
* Supports: '5s', '1m', '1h', '30000' (ms)
|
|
670
|
+
*/
|
|
671
|
+
private parseIntervalString;
|
|
672
|
+
/**
|
|
673
|
+
* Execute a tick for all applicable entities
|
|
674
|
+
*/
|
|
675
|
+
private executeTick;
|
|
676
|
+
/**
|
|
677
|
+
* Clean up all active ticks
|
|
678
|
+
*/
|
|
679
|
+
private cleanupTicks;
|
|
680
|
+
/**
|
|
681
|
+
* Unregister all orbitals and clean up
|
|
682
|
+
*/
|
|
683
|
+
unregisterAll(): void;
|
|
684
|
+
/**
|
|
685
|
+
* Process an event for an orbital
|
|
686
|
+
*/
|
|
687
|
+
processOrbitalEvent(orbitalName: string, request: OrbitalEventRequest): Promise<OrbitalEventResponse>;
|
|
688
|
+
/**
|
|
689
|
+
* Execute effects from a transition
|
|
690
|
+
*/
|
|
691
|
+
private executeEffects;
|
|
692
|
+
/**
|
|
693
|
+
* Create Express router for orbital API endpoints
|
|
694
|
+
*
|
|
695
|
+
* All data access goes through trait events with guards.
|
|
696
|
+
* No direct CRUD routes - use events with `fetch` effects.
|
|
697
|
+
*
|
|
698
|
+
* Routes:
|
|
699
|
+
* - GET / - List registered orbitals
|
|
700
|
+
* - GET /:orbital - Get orbital info and current states
|
|
701
|
+
* - POST /:orbital/events - Send event to orbital (includes data from `fetch` effects)
|
|
702
|
+
*/
|
|
703
|
+
router(): Router;
|
|
704
|
+
/**
|
|
705
|
+
* Get the event bus for manual event emission
|
|
706
|
+
*/
|
|
707
|
+
getEventBus(): EventBus;
|
|
708
|
+
/**
|
|
709
|
+
* Get state for a specific orbital/trait
|
|
710
|
+
*/
|
|
711
|
+
getState(orbitalName: string, traitName?: string): TraitState | Record<string, TraitState> | undefined;
|
|
712
|
+
/**
|
|
713
|
+
* List registered orbitals
|
|
714
|
+
*/
|
|
715
|
+
listOrbitals(): string[];
|
|
716
|
+
/**
|
|
717
|
+
* Check if an orbital is registered
|
|
718
|
+
*/
|
|
719
|
+
hasOrbital(name: string): boolean;
|
|
720
|
+
/**
|
|
721
|
+
* Get information about active ticks
|
|
722
|
+
*/
|
|
723
|
+
getActiveTicks(): Array<{
|
|
724
|
+
orbital: string;
|
|
725
|
+
trait: string;
|
|
726
|
+
tick: string;
|
|
727
|
+
interval: number | string;
|
|
728
|
+
hasGuard: boolean;
|
|
729
|
+
}>;
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Factory function to create a runtime instance
|
|
733
|
+
*/
|
|
734
|
+
declare function createOrbitalServerRuntime(config?: OrbitalServerRuntimeConfig): OrbitalServerRuntime;
|
|
735
|
+
|
|
736
|
+
export { type EntitySharingMap as E, type LoaderConfig as L, type OrbitalEventRequest as O, type PersistenceAdapter as P, type RuntimeOrbital as R, EventBus as a, type EventNamespaceMap as b, type OrbitalEventResponse as c, type OrbitalServerRuntimeConfig as d, type PreprocessOptions as e, type PreprocessResult as f, type PreprocessedSchema as g, type RuntimeOrbitalSchema as h, type RuntimeTrait as i, getIsolatedCollectionName as j, getNamespacedEvent as k, isNamespacedEvent as l, preprocessSchema as m, type EffectResult as n, OrbitalServerRuntime as o, parseNamespacedEvent as p, type RuntimeTraitTick as q, createOrbitalServerRuntime as r };
|