@almadar/runtime 2.2.1 → 2.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/dist/{OrbitalServerRuntime-YLqyxdjz.d.ts → OrbitalServerRuntime-Bel-jQ_o.d.ts} +3 -3
- package/dist/OrbitalServerRuntime.d.ts +2 -2
- package/dist/OrbitalServerRuntime.js +189 -2
- package/dist/OrbitalServerRuntime.js.map +1 -1
- package/dist/ServerBridge.d.ts +1 -1
- package/dist/{chunk-54P2HYHQ.js → chunk-GCRRQAGZ.js} +86 -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-54P2HYHQ.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;
|
|
@@ -1113,6 +1140,8 @@ var OrbitalServerRuntime = class {
|
|
|
1113
1140
|
*/
|
|
1114
1141
|
async executeEffects(registered, traitName, effects, payload, entityData, entityId, emittedEvents, fetchedData, clientEffects, effectResults, user) {
|
|
1115
1142
|
const entityType = registered.schema.entity.name;
|
|
1143
|
+
let bindingsRef = null;
|
|
1144
|
+
let contextRef = null;
|
|
1116
1145
|
const handlers = {
|
|
1117
1146
|
emit: (event, eventPayload) => {
|
|
1118
1147
|
if (this.config.debug) {
|
|
@@ -1319,12 +1348,165 @@ var OrbitalServerRuntime = class {
|
|
|
1319
1348
|
fetchedData[fetchEntityType] = entities;
|
|
1320
1349
|
result = entities;
|
|
1321
1350
|
}
|
|
1351
|
+
if (bindingsRef && result) {
|
|
1352
|
+
const records = Array.isArray(result) ? result : [result];
|
|
1353
|
+
if (records.length > 0) {
|
|
1354
|
+
const merged = Object.assign([...records], records[0]);
|
|
1355
|
+
bindingsRef[fetchEntityType] = merged;
|
|
1356
|
+
if (fetchEntityType === entityType) {
|
|
1357
|
+
bindingsRef.entity = merged;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1322
1361
|
return result;
|
|
1323
1362
|
} catch (error) {
|
|
1324
1363
|
console.error(`[OrbitalRuntime] Fetch error for ${fetchEntityType}:`, error);
|
|
1325
1364
|
return null;
|
|
1326
1365
|
}
|
|
1327
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
|
+
},
|
|
1328
1510
|
// Client-side effects - collect for forwarding to client
|
|
1329
1511
|
renderUI: (slot, pattern, props, priority) => {
|
|
1330
1512
|
clientEffects.push(["render-ui", slot, pattern, props, priority]);
|
|
@@ -1353,12 +1535,17 @@ var OrbitalServerRuntime = class {
|
|
|
1353
1535
|
user
|
|
1354
1536
|
// @user bindings from Firebase auth
|
|
1355
1537
|
};
|
|
1538
|
+
if (entityType) {
|
|
1539
|
+
bindings[entityType] = entityData;
|
|
1540
|
+
}
|
|
1541
|
+
bindingsRef = bindings;
|
|
1356
1542
|
const context = {
|
|
1357
1543
|
traitName,
|
|
1358
1544
|
state: state?.currentState || "unknown",
|
|
1359
1545
|
transition: "unknown",
|
|
1360
1546
|
entityId
|
|
1361
1547
|
};
|
|
1548
|
+
contextRef = context;
|
|
1362
1549
|
const executor = new EffectExecutor({
|
|
1363
1550
|
handlers,
|
|
1364
1551
|
bindings,
|