@almadar/runtime 2.5.0 → 2.6.1
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/dist/{OrbitalServerRuntime-Bel-jQ_o.d.ts → OrbitalServerRuntime-B-QeKtKd.d.ts} +186 -14
- package/dist/OrbitalServerRuntime.d.ts +2 -2
- package/dist/OrbitalServerRuntime.js +10 -9
- package/dist/OrbitalServerRuntime.js.map +1 -1
- package/dist/ServerBridge.d.ts +3 -2
- package/dist/ServerBridge.js.map +1 -1
- package/dist/{chunk-ICTFAD3I.js → chunk-ESNML4B4.js} +2 -2
- package/dist/chunk-ESNML4B4.js.map +1 -0
- package/dist/index.d.ts +13 -173
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/{types-BrbvZxzX.d.ts → types-DYcUvi4H.d.ts} +38 -20
- package/package.json +3 -3
- package/dist/chunk-ICTFAD3I.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
|
-
import { I as IEventBus,
|
|
3
|
-
import { OrbitalSchema, Orbital, Trait } from '@almadar/core';
|
|
2
|
+
import { I as IEventBus, f as RuntimeEvent, e as EventListener, U as Unsubscribe, T as TraitDefinition, R as RuntimeConfig, h as TransitionObserver, g as TraitState, i as TransitionResult, d as Effect, E as EffectHandlers } from './types-DYcUvi4H.js';
|
|
3
|
+
import { EventPayload, EntityRow, OrbitalSchema, Orbital, Trait } from '@almadar/core';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* EventBus - Platform-Agnostic Pub/Sub Implementation
|
|
@@ -48,7 +48,7 @@ declare class EventBus implements IEventBus {
|
|
|
48
48
|
* beyond `maxDepth`, the event is dropped and an error is logged.
|
|
49
49
|
* This prevents infinite loops from circular emit/listen chains.
|
|
50
50
|
*/
|
|
51
|
-
emit(type: string, payload?:
|
|
51
|
+
emit(type: string, payload?: EventPayload, source?: RuntimeEvent['source']): void;
|
|
52
52
|
/**
|
|
53
53
|
* Subscribe to an event type
|
|
54
54
|
*/
|
|
@@ -76,6 +76,168 @@ declare class EventBus implements IEventBus {
|
|
|
76
76
|
getListenerCount(type: string): number;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
/**
|
|
80
|
+
* StateMachineCore - Platform-Agnostic State Machine Logic
|
|
81
|
+
*
|
|
82
|
+
* Pure TypeScript implementation of trait state machine execution.
|
|
83
|
+
* Extracts the core logic from useTraitStateMachine for use on
|
|
84
|
+
* both client and server.
|
|
85
|
+
*
|
|
86
|
+
* @packageDocumentation
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Find the initial state for a trait definition.
|
|
91
|
+
*/
|
|
92
|
+
declare function findInitialState(trait: TraitDefinition): string;
|
|
93
|
+
/**
|
|
94
|
+
* Create initial trait state for a trait definition.
|
|
95
|
+
*/
|
|
96
|
+
declare function createInitialTraitState(trait: TraitDefinition): TraitState;
|
|
97
|
+
/**
|
|
98
|
+
* Find a matching transition from the current state for the given event.
|
|
99
|
+
*/
|
|
100
|
+
declare function findTransition(trait: TraitDefinition, currentState: string, eventKey: string): TraitDefinition['transitions'][0] | undefined;
|
|
101
|
+
/**
|
|
102
|
+
* Normalize event key - strip UI: prefix if present.
|
|
103
|
+
*/
|
|
104
|
+
declare function normalizeEventKey(eventKey: string): string;
|
|
105
|
+
/**
|
|
106
|
+
* Options for processing an event through the state machine.
|
|
107
|
+
*/
|
|
108
|
+
interface ProcessEventOptions {
|
|
109
|
+
/** Current trait state */
|
|
110
|
+
traitState: TraitState;
|
|
111
|
+
/** Trait definition */
|
|
112
|
+
trait: TraitDefinition;
|
|
113
|
+
/** Event key to process */
|
|
114
|
+
eventKey: string;
|
|
115
|
+
/** Event payload */
|
|
116
|
+
payload?: EventPayload;
|
|
117
|
+
/** Entity data for binding resolution */
|
|
118
|
+
entityData?: EntityRow;
|
|
119
|
+
/**
|
|
120
|
+
* Guard evaluation error handling mode. (RCG-02)
|
|
121
|
+
* - "permissive": Guard errors allow the transition (default, backwards-compatible)
|
|
122
|
+
* - "strict": Guard errors block the transition
|
|
123
|
+
*/
|
|
124
|
+
guardMode?: "strict" | "permissive";
|
|
125
|
+
/**
|
|
126
|
+
* When true, log warnings when bindings resolve to undefined. (RCG-01)
|
|
127
|
+
*/
|
|
128
|
+
strictBindings?: boolean;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Process an event through a trait's state machine.
|
|
132
|
+
*
|
|
133
|
+
* This is a pure function that:
|
|
134
|
+
* 1. Finds matching transitions
|
|
135
|
+
* 2. Evaluates guards
|
|
136
|
+
* 3. Returns the transition result (but does not execute effects)
|
|
137
|
+
*
|
|
138
|
+
* @returns TransitionResult with effects to execute
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```ts
|
|
142
|
+
* const result = processEvent({
|
|
143
|
+
* traitState: { traitName: 'Cart', currentState: 'empty', ... },
|
|
144
|
+
* trait: cartTraitDefinition,
|
|
145
|
+
* eventKey: 'ADD_ITEM',
|
|
146
|
+
* payload: { productId: '123' },
|
|
147
|
+
* });
|
|
148
|
+
*
|
|
149
|
+
* if (result.executed) {
|
|
150
|
+
* // Execute effects
|
|
151
|
+
* for (const effect of result.effects) {
|
|
152
|
+
* effectExecutor.execute(effect);
|
|
153
|
+
* }
|
|
154
|
+
* // Update state
|
|
155
|
+
* traitState.currentState = result.newState;
|
|
156
|
+
* }
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
declare function processEvent(options: ProcessEventOptions): TransitionResult;
|
|
160
|
+
declare class StateMachineManager {
|
|
161
|
+
private traits;
|
|
162
|
+
private states;
|
|
163
|
+
private config;
|
|
164
|
+
private observer?;
|
|
165
|
+
private queues;
|
|
166
|
+
private processing;
|
|
167
|
+
constructor(traits?: TraitDefinition[], config?: RuntimeConfig, observer?: TransitionObserver);
|
|
168
|
+
/**
|
|
169
|
+
* Set the transition observer for runtime verification.
|
|
170
|
+
* Wire this to `verificationRegistry.recordTransition()` to enable
|
|
171
|
+
* automatic verification tracking.
|
|
172
|
+
*/
|
|
173
|
+
setObserver(observer: TransitionObserver): void;
|
|
174
|
+
/**
|
|
175
|
+
* Add a trait to the manager.
|
|
176
|
+
*/
|
|
177
|
+
addTrait(trait: TraitDefinition): void;
|
|
178
|
+
/**
|
|
179
|
+
* Remove a trait from the manager.
|
|
180
|
+
*/
|
|
181
|
+
removeTrait(traitName: string): void;
|
|
182
|
+
/**
|
|
183
|
+
* Get current state for a trait.
|
|
184
|
+
*/
|
|
185
|
+
getState(traitName: string): TraitState | undefined;
|
|
186
|
+
/**
|
|
187
|
+
* Get all current states.
|
|
188
|
+
*/
|
|
189
|
+
getAllStates(): Map<string, TraitState>;
|
|
190
|
+
/**
|
|
191
|
+
* Check if a trait can handle an event from its current state.
|
|
192
|
+
*/
|
|
193
|
+
canHandleEvent(traitName: string, eventKey: string): boolean;
|
|
194
|
+
/**
|
|
195
|
+
* Send an event to all traits.
|
|
196
|
+
*
|
|
197
|
+
* @returns Array of transition results (one per trait that had a matching transition)
|
|
198
|
+
*/
|
|
199
|
+
sendEvent(eventKey: string, payload?: EventPayload, entityData?: EntityRow): Array<{
|
|
200
|
+
traitName: string;
|
|
201
|
+
result: TransitionResult;
|
|
202
|
+
}>;
|
|
203
|
+
/**
|
|
204
|
+
* Enqueue an event into every trait's per-trait queue.
|
|
205
|
+
*
|
|
206
|
+
* Events are not processed immediately. Call `drainQueue()` for each
|
|
207
|
+
* trait to process them sequentially (actor-model guarantee: one event
|
|
208
|
+
* at a time per trait, effects fully awaited before the next event).
|
|
209
|
+
*/
|
|
210
|
+
enqueueEvent(eventKey: string, payload?: EventPayload, entityData?: EntityRow): void;
|
|
211
|
+
/**
|
|
212
|
+
* Drain a single trait's event queue, processing events sequentially.
|
|
213
|
+
*
|
|
214
|
+
* This is the core actor loop: each event is fully processed (including
|
|
215
|
+
* awaiting all effects) before the next event is dequeued. If the queue
|
|
216
|
+
* is already being drained for this trait, this call is a no-op (the
|
|
217
|
+
* running drain will pick up newly enqueued events).
|
|
218
|
+
*
|
|
219
|
+
* @param traitName - Which trait's queue to drain
|
|
220
|
+
* @param executeEffects - Async callback to run effects for a successful transition
|
|
221
|
+
*/
|
|
222
|
+
drainQueue(traitName: string, executeEffects: (traitName: string, result: TransitionResult, payload?: EventPayload) => Promise<void>): Promise<void>;
|
|
223
|
+
/**
|
|
224
|
+
* Check whether a trait's queue is currently being drained.
|
|
225
|
+
*/
|
|
226
|
+
isProcessing(traitName: string): boolean;
|
|
227
|
+
/**
|
|
228
|
+
* Get the number of pending events in a trait's queue.
|
|
229
|
+
*/
|
|
230
|
+
getQueueLength(traitName: string): number;
|
|
231
|
+
/**
|
|
232
|
+
* Reset a trait to its initial state.
|
|
233
|
+
*/
|
|
234
|
+
resetTrait(traitName: string): void;
|
|
235
|
+
/**
|
|
236
|
+
* Reset all traits to initial states.
|
|
237
|
+
*/
|
|
238
|
+
resetAll(): void;
|
|
239
|
+
}
|
|
240
|
+
|
|
79
241
|
/**
|
|
80
242
|
* External Orbital Loader
|
|
81
243
|
*
|
|
@@ -436,7 +598,7 @@ interface RuntimeOrbital {
|
|
|
436
598
|
};
|
|
437
599
|
}>;
|
|
438
600
|
/** Pre-defined entity instances to seed on registration */
|
|
439
|
-
instances?: Array<
|
|
601
|
+
instances?: Array<EntityRow>;
|
|
440
602
|
};
|
|
441
603
|
traits: RuntimeTrait[];
|
|
442
604
|
}
|
|
@@ -471,18 +633,26 @@ interface RuntimeTrait {
|
|
|
471
633
|
listens?: Array<{
|
|
472
634
|
event: string;
|
|
473
635
|
triggers: string;
|
|
474
|
-
payloadMapping?:
|
|
636
|
+
payloadMapping?: EventPayload;
|
|
475
637
|
}>;
|
|
476
638
|
emits?: string[];
|
|
477
639
|
/** Scheduled ticks for this trait */
|
|
478
640
|
ticks?: RuntimeTraitTick[];
|
|
479
641
|
}
|
|
642
|
+
/**
|
|
643
|
+
* Registered orbital with runtime state
|
|
644
|
+
*/
|
|
645
|
+
interface RegisteredOrbital {
|
|
646
|
+
schema: RuntimeOrbital;
|
|
647
|
+
manager: StateMachineManager;
|
|
648
|
+
entityData: Map<string, EntityRow>;
|
|
649
|
+
}
|
|
480
650
|
/**
|
|
481
651
|
* Event sent from client to server
|
|
482
652
|
*/
|
|
483
653
|
interface OrbitalEventRequest {
|
|
484
654
|
event: string;
|
|
485
|
-
payload?:
|
|
655
|
+
payload?: EventPayload;
|
|
486
656
|
entityId?: string;
|
|
487
657
|
/** User context for @user bindings (from Firebase auth) */
|
|
488
658
|
user?: {
|
|
@@ -504,7 +674,9 @@ interface OrbitalEventResponse {
|
|
|
504
674
|
payload?: unknown;
|
|
505
675
|
}>;
|
|
506
676
|
/** Entity data fetched by `fetch` effects - keyed by entity type */
|
|
507
|
-
data?:
|
|
677
|
+
data?: {
|
|
678
|
+
[entityType: string]: EntityRow | EntityRow[];
|
|
679
|
+
};
|
|
508
680
|
/** Client-side effects to execute (render-ui, navigate, notify) */
|
|
509
681
|
clientEffects?: Array<unknown>;
|
|
510
682
|
/** Results from server-side effects (persist, call-service, set) */
|
|
@@ -523,7 +695,7 @@ interface EffectResult {
|
|
|
523
695
|
/** Entity type affected (for persist/set/ref/deref/swap) */
|
|
524
696
|
entityType?: string;
|
|
525
697
|
/** Result data from the effect */
|
|
526
|
-
data?:
|
|
698
|
+
data?: EntityRow;
|
|
527
699
|
/** Whether the effect succeeded */
|
|
528
700
|
success: boolean;
|
|
529
701
|
/** Error message if failed */
|
|
@@ -583,16 +755,16 @@ interface OrbitalServerRuntimeConfig {
|
|
|
583
755
|
* Adapter for persisting entity data
|
|
584
756
|
*/
|
|
585
757
|
interface PersistenceAdapter {
|
|
586
|
-
create(entityType: string, data:
|
|
758
|
+
create(entityType: string, data: EntityRow): Promise<{
|
|
587
759
|
id: string;
|
|
588
760
|
}>;
|
|
589
|
-
update(entityType: string, id: string, data:
|
|
761
|
+
update(entityType: string, id: string, data: EntityRow): Promise<void>;
|
|
590
762
|
delete(entityType: string, id: string): Promise<void>;
|
|
591
|
-
getById(entityType: string, id: string): Promise<
|
|
592
|
-
list(entityType: string): Promise<Array<
|
|
763
|
+
getById(entityType: string, id: string): Promise<EntityRow | null>;
|
|
764
|
+
list(entityType: string): Promise<Array<EntityRow>>;
|
|
593
765
|
}
|
|
594
766
|
declare class OrbitalServerRuntime {
|
|
595
|
-
|
|
767
|
+
protected orbitals: Map<string, RegisteredOrbital>;
|
|
596
768
|
private eventBus;
|
|
597
769
|
private config;
|
|
598
770
|
private persistence;
|
|
@@ -782,4 +954,4 @@ declare class OrbitalServerRuntime {
|
|
|
782
954
|
*/
|
|
783
955
|
declare function createOrbitalServerRuntime(config?: OrbitalServerRuntimeConfig): OrbitalServerRuntime;
|
|
784
956
|
|
|
785
|
-
export { type EntitySharingMap as E, type LoaderConfig as L, type OrbitalEventRequest as O, type PersistenceAdapter as P, type
|
|
957
|
+
export { type EntitySharingMap as E, type LoaderConfig as L, type OrbitalEventRequest as O, type PersistenceAdapter as P, type RegisteredOrbital as R, StateMachineManager as S, 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 ProcessEventOptions as h, type RuntimeOrbital as i, type RuntimeOrbitalSchema as j, type RuntimeTrait as k, createInitialTraitState as l, findInitialState as m, findTransition as n, getIsolatedCollectionName as o, getNamespacedEvent as p, isNamespacedEvent as q, normalizeEventKey as r, parseNamespacedEvent as s, preprocessSchema as t, processEvent as u, type EffectResult as v, OrbitalServerRuntime as w, type RuntimeTraitTick as x, createOrbitalServerRuntime as y };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import 'express';
|
|
2
|
-
export {
|
|
3
|
-
import './types-
|
|
2
|
+
export { v as EffectResult, L as LoaderConfig, O as OrbitalEventRequest, c as OrbitalEventResponse, w as OrbitalServerRuntime, d as OrbitalServerRuntimeConfig, P as PersistenceAdapter, R as RegisteredOrbital, i as RuntimeOrbital, j as RuntimeOrbitalSchema, k as RuntimeTrait, x as RuntimeTraitTick, y as createOrbitalServerRuntime } from './OrbitalServerRuntime-B-QeKtKd.js';
|
|
3
|
+
import './types-DYcUvi4H.js';
|
|
4
4
|
import '@almadar/core';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EventBus, createUnifiedLoader, preprocessSchema, StateMachineManager, createContextFromBindings, EffectExecutor } from './chunk-
|
|
1
|
+
import { EventBus, createUnifiedLoader, preprocessSchema, StateMachineManager, createContextFromBindings, EffectExecutor } from './chunk-ESNML4B4.js';
|
|
2
2
|
import { Router } from 'express';
|
|
3
3
|
import { evaluateGuard, evaluate } from '@almadar/evaluator';
|
|
4
4
|
import { faker } from '@faker-js/faker';
|
|
@@ -146,8 +146,9 @@ var MockPersistenceAdapter = class {
|
|
|
146
146
|
return null;
|
|
147
147
|
// Relations need special handling
|
|
148
148
|
case "array":
|
|
149
|
+
return [];
|
|
149
150
|
case "object":
|
|
150
|
-
return
|
|
151
|
+
return null;
|
|
151
152
|
default:
|
|
152
153
|
return this.generateStringValue(entityName, field, index);
|
|
153
154
|
}
|
|
@@ -1727,15 +1728,17 @@ var OrbitalServerRuntime = class {
|
|
|
1727
1728
|
const populatedFieldName = includeField.endsWith("Id") ? includeField.slice(0, -2) : includeField;
|
|
1728
1729
|
for (const entity of entities) {
|
|
1729
1730
|
const fkValue = entity[foreignKeyField];
|
|
1731
|
+
const entityRecord = entity;
|
|
1730
1732
|
if (cardinality === "one" || cardinality === "many-to-one") {
|
|
1731
1733
|
if (typeof fkValue === "string" && relatedEntities.has(fkValue)) {
|
|
1732
|
-
|
|
1734
|
+
entityRecord[populatedFieldName] = relatedEntities.get(fkValue);
|
|
1733
1735
|
}
|
|
1734
1736
|
} else {
|
|
1735
1737
|
if (Array.isArray(fkValue)) {
|
|
1736
|
-
|
|
1738
|
+
const fkIds = fkValue.filter((id) => typeof id === "string");
|
|
1739
|
+
entityRecord[populatedFieldName] = fkIds.map((id) => relatedEntities.get(id)).filter(Boolean);
|
|
1737
1740
|
} else if (typeof fkValue === "string" && relatedEntities.has(fkValue)) {
|
|
1738
|
-
|
|
1741
|
+
entityRecord[populatedFieldName] = [relatedEntities.get(fkValue)];
|
|
1739
1742
|
}
|
|
1740
1743
|
}
|
|
1741
1744
|
}
|
|
@@ -1802,10 +1805,8 @@ var OrbitalServerRuntime = class {
|
|
|
1802
1805
|
const orbitalName = req.params.orbital;
|
|
1803
1806
|
const firebaseUser = req.firebaseUser;
|
|
1804
1807
|
const user = firebaseUser ? {
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
displayName: firebaseUser.name,
|
|
1808
|
-
...firebaseUser
|
|
1808
|
+
...firebaseUser,
|
|
1809
|
+
displayName: firebaseUser.name ?? firebaseUser.displayName
|
|
1809
1810
|
} : void 0;
|
|
1810
1811
|
const result = await this.processOrbitalEvent(orbitalName, {
|
|
1811
1812
|
...req.body,
|