@almadar/runtime 2.2.2 → 2.4.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/dist/{OrbitalServerRuntime-YLqyxdjz.d.ts → OrbitalServerRuntime-Bel-jQ_o.d.ts} +3 -3
- package/dist/OrbitalServerRuntime.d.ts +2 -2
- package/dist/OrbitalServerRuntime.js +174 -2
- package/dist/OrbitalServerRuntime.js.map +1 -1
- package/dist/ServerBridge.d.ts +1 -1
- package/dist/{chunk-57PUFAKH.js → chunk-GCRRQAGZ.js} +81 -7
- package/dist/chunk-GCRRQAGZ.js.map +1 -0
- package/dist/index.d.ts +3 -5
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/{types-E5o2Jqe6.d.ts → types-BrbvZxzX.d.ts} +19 -0
- package/package.json +1 -1
- package/dist/chunk-57PUFAKH.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
|
-
import { I as IEventBus, i as RuntimeEvent, h as EventListener, U as Unsubscribe, E as EffectHandlers, g as Effect, T as TraitState } from './types-
|
|
2
|
+
import { I as IEventBus, i as RuntimeEvent, h as EventListener, U as Unsubscribe, E as EffectHandlers, g as Effect, T as TraitState } from './types-BrbvZxzX.js';
|
|
3
3
|
import { OrbitalSchema, Orbital, Trait } from '@almadar/core';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -517,10 +517,10 @@ interface OrbitalEventResponse {
|
|
|
517
517
|
*/
|
|
518
518
|
interface EffectResult {
|
|
519
519
|
/** Effect type that was executed */
|
|
520
|
-
effect: 'persist' | 'call-service' | 'set';
|
|
520
|
+
effect: 'persist' | 'call-service' | 'set' | 'ref' | 'deref' | 'swap' | 'atomic';
|
|
521
521
|
/** Action performed (e.g., 'create', 'update', 'delete' for persist) */
|
|
522
522
|
action?: string;
|
|
523
|
-
/** Entity type affected (for persist/set) */
|
|
523
|
+
/** Entity type affected (for persist/set/ref/deref/swap) */
|
|
524
524
|
entityType?: string;
|
|
525
525
|
/** Result data from the effect */
|
|
526
526
|
data?: Record<string, unknown>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import 'express';
|
|
2
|
-
export { n as EffectResult, L as LoaderConfig, O as OrbitalEventRequest, c as OrbitalEventResponse, o as OrbitalServerRuntime, d as OrbitalServerRuntimeConfig, P as PersistenceAdapter, R as RuntimeOrbital, h as RuntimeOrbitalSchema, i as RuntimeTrait, q as RuntimeTraitTick, r as createOrbitalServerRuntime } from './OrbitalServerRuntime-
|
|
3
|
-
import './types-
|
|
2
|
+
export { n as EffectResult, L as LoaderConfig, O as OrbitalEventRequest, c as OrbitalEventResponse, o as OrbitalServerRuntime, d as OrbitalServerRuntimeConfig, P as PersistenceAdapter, R as RuntimeOrbital, h as RuntimeOrbitalSchema, i as RuntimeTrait, q as RuntimeTraitTick, r as createOrbitalServerRuntime } from './OrbitalServerRuntime-Bel-jQ_o.js';
|
|
3
|
+
import './types-BrbvZxzX.js';
|
|
4
4
|
import '@almadar/core';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { EventBus, createUnifiedLoader, preprocessSchema, StateMachineManager, createContextFromBindings, EffectExecutor } from './chunk-
|
|
1
|
+
import { EventBus, createUnifiedLoader, preprocessSchema, StateMachineManager, createContextFromBindings, EffectExecutor } from './chunk-GCRRQAGZ.js';
|
|
2
2
|
import { Router } from 'express';
|
|
3
|
-
import { evaluateGuard } from '@almadar/evaluator';
|
|
3
|
+
import { evaluateGuard, evaluate } from '@almadar/evaluator';
|
|
4
4
|
import { faker } from '@faker-js/faker';
|
|
5
5
|
import * as fs from 'fs';
|
|
6
6
|
import * as net from 'net';
|
|
@@ -1087,6 +1087,33 @@ var OrbitalServerRuntime = class {
|
|
|
1087
1087
|
);
|
|
1088
1088
|
}
|
|
1089
1089
|
}
|
|
1090
|
+
const persistedTypes = /* @__PURE__ */ new Set();
|
|
1091
|
+
for (const er of effectResults) {
|
|
1092
|
+
if ((er.effect === "persist" || er.effect === "set" || er.effect === "swap") && er.success && er.entityType) {
|
|
1093
|
+
persistedTypes.add(er.entityType);
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
const refTypes = /* @__PURE__ */ new Set();
|
|
1097
|
+
for (const trait of registered.schema.traits || []) {
|
|
1098
|
+
const sm = trait.stateMachine;
|
|
1099
|
+
const transitions = sm?.transitions ?? trait.transitions ?? [];
|
|
1100
|
+
for (const trans of transitions) {
|
|
1101
|
+
for (const eff of trans.effects ?? []) {
|
|
1102
|
+
if (Array.isArray(eff) && eff[0] === "ref" && typeof eff[1] === "string") {
|
|
1103
|
+
refTypes.add(eff[1]);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
for (const mutatedEntityType of persistedTypes) {
|
|
1109
|
+
if (refTypes.has(mutatedEntityType)) {
|
|
1110
|
+
try {
|
|
1111
|
+
const fresh = await this.persistence.list(mutatedEntityType);
|
|
1112
|
+
fetchedData[mutatedEntityType] = fresh;
|
|
1113
|
+
} catch {
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1090
1117
|
const states = {};
|
|
1091
1118
|
for (const [name, state] of registered.manager.getAllStates()) {
|
|
1092
1119
|
states[name] = state.currentState;
|
|
@@ -1114,6 +1141,7 @@ var OrbitalServerRuntime = class {
|
|
|
1114
1141
|
async executeEffects(registered, traitName, effects, payload, entityData, entityId, emittedEvents, fetchedData, clientEffects, effectResults, user) {
|
|
1115
1142
|
const entityType = registered.schema.entity.name;
|
|
1116
1143
|
let bindingsRef = null;
|
|
1144
|
+
let contextRef = null;
|
|
1117
1145
|
const handlers = {
|
|
1118
1146
|
emit: (event, eventPayload) => {
|
|
1119
1147
|
if (this.config.debug) {
|
|
@@ -1336,6 +1364,149 @@ var OrbitalServerRuntime = class {
|
|
|
1336
1364
|
return null;
|
|
1337
1365
|
}
|
|
1338
1366
|
},
|
|
1367
|
+
// Resource operators: ref, deref, swap, watch, atomic
|
|
1368
|
+
ref: async (refEntityType, options) => {
|
|
1369
|
+
try {
|
|
1370
|
+
return await handlers.fetch(refEntityType, options);
|
|
1371
|
+
} catch (error) {
|
|
1372
|
+
console.error(`[OrbitalRuntime] ref error for ${refEntityType}:`, error);
|
|
1373
|
+
return null;
|
|
1374
|
+
}
|
|
1375
|
+
},
|
|
1376
|
+
deref: async (derefEntityType, options) => {
|
|
1377
|
+
try {
|
|
1378
|
+
let result = null;
|
|
1379
|
+
if (options?.id) {
|
|
1380
|
+
const entity = await this.persistence.getById(derefEntityType, options.id);
|
|
1381
|
+
if (entity) {
|
|
1382
|
+
fetchedData[derefEntityType] = [entity];
|
|
1383
|
+
result = entity;
|
|
1384
|
+
}
|
|
1385
|
+
} else {
|
|
1386
|
+
const entities = await this.persistence.list(derefEntityType);
|
|
1387
|
+
fetchedData[derefEntityType] = entities;
|
|
1388
|
+
result = entities;
|
|
1389
|
+
}
|
|
1390
|
+
if (bindingsRef && result) {
|
|
1391
|
+
const records = Array.isArray(result) ? result : [result];
|
|
1392
|
+
if (records.length > 0) {
|
|
1393
|
+
const merged = Object.assign([...records], records[0]);
|
|
1394
|
+
bindingsRef[derefEntityType] = merged;
|
|
1395
|
+
if (derefEntityType === entityType) {
|
|
1396
|
+
bindingsRef.entity = merged;
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
effectResults.push({
|
|
1401
|
+
effect: "deref",
|
|
1402
|
+
entityType: derefEntityType,
|
|
1403
|
+
success: true
|
|
1404
|
+
});
|
|
1405
|
+
return result;
|
|
1406
|
+
} catch (error) {
|
|
1407
|
+
effectResults.push({
|
|
1408
|
+
effect: "deref",
|
|
1409
|
+
entityType: derefEntityType,
|
|
1410
|
+
success: false,
|
|
1411
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1412
|
+
});
|
|
1413
|
+
return null;
|
|
1414
|
+
}
|
|
1415
|
+
},
|
|
1416
|
+
swap: async (swapEntityType, swapEntityId, transform) => {
|
|
1417
|
+
try {
|
|
1418
|
+
const current = await this.persistence.getById(swapEntityType, swapEntityId);
|
|
1419
|
+
if (!current) {
|
|
1420
|
+
effectResults.push({
|
|
1421
|
+
effect: "swap",
|
|
1422
|
+
entityType: swapEntityType,
|
|
1423
|
+
success: false,
|
|
1424
|
+
error: `Entity ${swapEntityType}/${swapEntityId} not found`
|
|
1425
|
+
});
|
|
1426
|
+
return null;
|
|
1427
|
+
}
|
|
1428
|
+
const ctx = createContextFromBindings({
|
|
1429
|
+
current,
|
|
1430
|
+
entity: entityData,
|
|
1431
|
+
payload
|
|
1432
|
+
});
|
|
1433
|
+
let newData;
|
|
1434
|
+
if (Array.isArray(transform)) {
|
|
1435
|
+
const result = evaluate(
|
|
1436
|
+
transform,
|
|
1437
|
+
ctx
|
|
1438
|
+
);
|
|
1439
|
+
if (result && typeof result === "object" && !Array.isArray(result)) {
|
|
1440
|
+
newData = result;
|
|
1441
|
+
} else {
|
|
1442
|
+
newData = current;
|
|
1443
|
+
}
|
|
1444
|
+
} else if (typeof transform === "object" && transform !== null) {
|
|
1445
|
+
newData = { ...current, ...transform };
|
|
1446
|
+
} else {
|
|
1447
|
+
effectResults.push({
|
|
1448
|
+
effect: "swap",
|
|
1449
|
+
entityType: swapEntityType,
|
|
1450
|
+
success: false,
|
|
1451
|
+
error: "swap! transform must be an S-expression or object"
|
|
1452
|
+
});
|
|
1453
|
+
return null;
|
|
1454
|
+
}
|
|
1455
|
+
await this.persistence.update(swapEntityType, swapEntityId, newData);
|
|
1456
|
+
effectResults.push({
|
|
1457
|
+
effect: "swap",
|
|
1458
|
+
entityType: swapEntityType,
|
|
1459
|
+
data: { id: swapEntityId, ...newData },
|
|
1460
|
+
success: true
|
|
1461
|
+
});
|
|
1462
|
+
return newData;
|
|
1463
|
+
} catch (error) {
|
|
1464
|
+
effectResults.push({
|
|
1465
|
+
effect: "swap",
|
|
1466
|
+
entityType: swapEntityType,
|
|
1467
|
+
success: false,
|
|
1468
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1469
|
+
});
|
|
1470
|
+
return null;
|
|
1471
|
+
}
|
|
1472
|
+
},
|
|
1473
|
+
watch: (_watchEntityType, _watchOptions) => {
|
|
1474
|
+
if (this.config.debug) {
|
|
1475
|
+
console.log(`[OrbitalRuntime] watch is a no-op on server: ${_watchEntityType}`);
|
|
1476
|
+
}
|
|
1477
|
+
},
|
|
1478
|
+
atomic: async (atomicEffects) => {
|
|
1479
|
+
let atomicFailed = false;
|
|
1480
|
+
let atomicError = "";
|
|
1481
|
+
const atomicExecutor = new EffectExecutor({
|
|
1482
|
+
handlers,
|
|
1483
|
+
bindings: bindingsRef ?? {},
|
|
1484
|
+
context: contextRef ?? { traitName, state: "unknown", transition: "unknown" },
|
|
1485
|
+
debug: this.config.debug
|
|
1486
|
+
});
|
|
1487
|
+
for (const innerEffect of atomicEffects) {
|
|
1488
|
+
if (atomicFailed) break;
|
|
1489
|
+
try {
|
|
1490
|
+
await atomicExecutor.execute(innerEffect);
|
|
1491
|
+
} catch (err) {
|
|
1492
|
+
atomicFailed = true;
|
|
1493
|
+
atomicError = err instanceof Error ? err.message : String(err);
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
if (atomicFailed) {
|
|
1497
|
+
effectResults.push({
|
|
1498
|
+
effect: "atomic",
|
|
1499
|
+
success: false,
|
|
1500
|
+
error: `Atomic block failed: ${atomicError}`
|
|
1501
|
+
});
|
|
1502
|
+
} else {
|
|
1503
|
+
effectResults.push({
|
|
1504
|
+
effect: "atomic",
|
|
1505
|
+
success: true,
|
|
1506
|
+
data: { innerCount: atomicEffects.length }
|
|
1507
|
+
});
|
|
1508
|
+
}
|
|
1509
|
+
},
|
|
1339
1510
|
// Client-side effects - collect for forwarding to client
|
|
1340
1511
|
renderUI: (slot, pattern, props, priority) => {
|
|
1341
1512
|
clientEffects.push(["render-ui", slot, pattern, props, priority]);
|
|
@@ -1374,6 +1545,7 @@ var OrbitalServerRuntime = class {
|
|
|
1374
1545
|
transition: "unknown",
|
|
1375
1546
|
entityId
|
|
1376
1547
|
};
|
|
1548
|
+
contextRef = context;
|
|
1377
1549
|
const executor = new EffectExecutor({
|
|
1378
1550
|
handlers,
|
|
1379
1551
|
bindings,
|