@almadar/runtime 3.1.4 → 3.2.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-DWJYcIJG.d.ts → OrbitalServerRuntime-CQsVhY4Y.d.ts} +1 -1
- package/dist/OrbitalServerRuntime.d.ts +2 -2
- package/dist/OrbitalServerRuntime.js +41 -17
- package/dist/OrbitalServerRuntime.js.map +1 -1
- package/dist/ServerBridge.d.ts +1 -1
- package/dist/{chunk-6PAKTVTR.js → chunk-PXASRZKG.js} +157 -29
- package/dist/chunk-PXASRZKG.js.map +1 -0
- package/dist/index.d.ts +13 -3
- package/dist/index.js +1 -1
- package/dist/{types-CM6txTNy.d.ts → types-B8OfRFfV.d.ts} +14 -15
- package/package.json +2 -2
- package/dist/chunk-6PAKTVTR.js.map +0 -1
package/dist/ServerBridge.d.ts
CHANGED
|
@@ -177,6 +177,14 @@ function createLogger(namespace) {
|
|
|
177
177
|
|
|
178
178
|
// src/BindingResolver.ts
|
|
179
179
|
var bindLog = createLogger("almadar:runtime:bindings");
|
|
180
|
+
var CLIENT_ONLY_BINDING_ROOTS = /* @__PURE__ */ new Set(["trait"]);
|
|
181
|
+
function isClientOnlyBinding(value) {
|
|
182
|
+
if (!value.startsWith("@")) return false;
|
|
183
|
+
const afterAt = value.slice(1);
|
|
184
|
+
const firstDot = afterAt.indexOf(".");
|
|
185
|
+
const root = firstDot === -1 ? afterAt : afterAt.slice(0, firstDot);
|
|
186
|
+
return CLIENT_ONLY_BINDING_ROOTS.has(root);
|
|
187
|
+
}
|
|
180
188
|
function interpolateProps(props, ctx) {
|
|
181
189
|
const result = {};
|
|
182
190
|
for (const [key, value] of Object.entries(props)) {
|
|
@@ -201,6 +209,10 @@ function interpolateValue(value, ctx) {
|
|
|
201
209
|
}
|
|
202
210
|
function interpolateString(value, ctx) {
|
|
203
211
|
if (value.startsWith("@") && isPureBinding(value)) {
|
|
212
|
+
if (isClientOnlyBinding(value)) {
|
|
213
|
+
bindLog.debug("passthrough:client-only", { binding: value });
|
|
214
|
+
return value;
|
|
215
|
+
}
|
|
204
216
|
const resolved = resolveBinding(value, ctx);
|
|
205
217
|
bindLog.debug("resolve", { binding: value, resolvedType: typeof resolved });
|
|
206
218
|
return resolved;
|
|
@@ -215,6 +227,9 @@ function isPureBinding(value) {
|
|
|
215
227
|
}
|
|
216
228
|
function interpolateEmbeddedBindings(value, ctx) {
|
|
217
229
|
return value.replace(/@[\w]+(?:\.[\w]+)*/g, (match) => {
|
|
230
|
+
if (isClientOnlyBinding(match)) {
|
|
231
|
+
return match;
|
|
232
|
+
}
|
|
218
233
|
const resolved = resolveBinding(match, ctx);
|
|
219
234
|
return resolved !== void 0 ? String(resolved) : match;
|
|
220
235
|
});
|
|
@@ -886,13 +901,13 @@ var EffectExecutor = class {
|
|
|
886
901
|
}
|
|
887
902
|
const { operator, args } = parsed;
|
|
888
903
|
const isCompound = operator === "do" || operator === "when";
|
|
889
|
-
const
|
|
904
|
+
const isSetPathForm = operator === "set" && args.length >= 2 && typeof args[0] === "string" && args[0].startsWith("@entity.");
|
|
890
905
|
let resolvedArgs;
|
|
891
906
|
if (isCompound) {
|
|
892
907
|
resolvedArgs = args;
|
|
893
|
-
} else if (
|
|
908
|
+
} else if (isSetPathForm) {
|
|
894
909
|
const ctx = createContextFromBindings(this.bindings, this.strictBindings, this.contextExtensions);
|
|
895
|
-
resolvedArgs = [args[0], interpolateValue(
|
|
910
|
+
resolvedArgs = [args[0], ...args.slice(1).map((a) => interpolateValue(a, ctx))];
|
|
896
911
|
} else {
|
|
897
912
|
resolvedArgs = resolveArgs(args, this.bindings, this.strictBindings, this.contextExtensions);
|
|
898
913
|
}
|
|
@@ -972,6 +987,59 @@ var EffectExecutor = class {
|
|
|
972
987
|
return results;
|
|
973
988
|
}
|
|
974
989
|
// ==========================================================================
|
|
990
|
+
// `emit:` config extraction — close-the-circuit on async/reactive ops.
|
|
991
|
+
//
|
|
992
|
+
// `fetch`, `persist`, `call-service`, `set`, `ref`, `os/watch-*` may carry
|
|
993
|
+
// an `emit:` key in their options object. After the effect's work finishes,
|
|
994
|
+
// the runtime fires the author-configured bus event so downstream state
|
|
995
|
+
// machines can branch on success/failure without stitching async/sequence.
|
|
996
|
+
//
|
|
997
|
+
// See `docs/Almadar_Std_Gaps.md` §3.1 and the emit-config plan for the
|
|
998
|
+
// semantics. The compiled-path shell does the same work in generated JS.
|
|
999
|
+
// ==========================================================================
|
|
1000
|
+
extractEmitConfig(rawOpt) {
|
|
1001
|
+
if (!rawOpt || typeof rawOpt !== "object" || Array.isArray(rawOpt)) {
|
|
1002
|
+
return void 0;
|
|
1003
|
+
}
|
|
1004
|
+
const obj = rawOpt;
|
|
1005
|
+
const emitBlock = obj.emit;
|
|
1006
|
+
if (!emitBlock || typeof emitBlock !== "object" || Array.isArray(emitBlock)) {
|
|
1007
|
+
return void 0;
|
|
1008
|
+
}
|
|
1009
|
+
const block = emitBlock;
|
|
1010
|
+
const asStr = (v) => typeof v === "string" ? v : void 0;
|
|
1011
|
+
return {
|
|
1012
|
+
success: asStr(block.success),
|
|
1013
|
+
failure: asStr(block.failure),
|
|
1014
|
+
on_change: asStr(block.on_change) ?? asStr(block.onChange),
|
|
1015
|
+
on_message: asStr(block.on_message) ?? asStr(block.onMessage)
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
1018
|
+
emitSuccess(emit, key, payload) {
|
|
1019
|
+
const eventName = emit?.[key];
|
|
1020
|
+
if (eventName) {
|
|
1021
|
+
this.handlers.emit(eventName, payload);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
emitFailure(emit, err) {
|
|
1025
|
+
if (!emit?.failure) return;
|
|
1026
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
1027
|
+
this.handlers.emit(emit.failure, { error });
|
|
1028
|
+
}
|
|
1029
|
+
/**
|
|
1030
|
+
* Narrow the generic emit config into the `os/watch-*` handler surface
|
|
1031
|
+
* (only `on_message` + `failure` are meaningful for streaming ops).
|
|
1032
|
+
* Returns `undefined` when neither field is set so handlers can test
|
|
1033
|
+
* with a single `if (emit)` guard.
|
|
1034
|
+
*/
|
|
1035
|
+
osEmit(emit) {
|
|
1036
|
+
if (!emit || !emit.on_message && !emit.failure) return void 0;
|
|
1037
|
+
return {
|
|
1038
|
+
on_message: emit.on_message,
|
|
1039
|
+
failure: emit.failure
|
|
1040
|
+
};
|
|
1041
|
+
}
|
|
1042
|
+
// ==========================================================================
|
|
975
1043
|
// Effect Dispatch
|
|
976
1044
|
// ==========================================================================
|
|
977
1045
|
async dispatch(operator, args) {
|
|
@@ -988,10 +1056,12 @@ var EffectExecutor = class {
|
|
|
988
1056
|
let entityId;
|
|
989
1057
|
let field;
|
|
990
1058
|
let value;
|
|
991
|
-
|
|
1059
|
+
let emitCfg;
|
|
1060
|
+
if (typeof args[0] === "string" && args[0].startsWith("@entity.")) {
|
|
992
1061
|
const path = args[0];
|
|
993
1062
|
field = path.slice("@entity.".length);
|
|
994
1063
|
value = args[1];
|
|
1064
|
+
emitCfg = this.extractEmitConfig(args[2]);
|
|
995
1065
|
entityId = typeof entity?.["id"] === "string" ? entity["id"] : void 0;
|
|
996
1066
|
if (!entityId) {
|
|
997
1067
|
effectLog.warn("set:missing-entity-id", { path });
|
|
@@ -1001,22 +1071,33 @@ var EffectExecutor = class {
|
|
|
1001
1071
|
entityId = args[0];
|
|
1002
1072
|
field = args[1];
|
|
1003
1073
|
value = args[2];
|
|
1074
|
+
emitCfg = this.extractEmitConfig(args[3]);
|
|
1004
1075
|
}
|
|
1005
1076
|
this.handlers.set(entityId, field, value);
|
|
1006
1077
|
if (entity && entity["id"] === entityId) {
|
|
1007
1078
|
entity[field] = value;
|
|
1008
1079
|
}
|
|
1080
|
+
this.emitSuccess(emitCfg, "success", value);
|
|
1009
1081
|
break;
|
|
1010
1082
|
}
|
|
1011
1083
|
case "persist": {
|
|
1012
1084
|
const action = args[0];
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1085
|
+
const last = args[args.length - 1];
|
|
1086
|
+
const emitCfg = last && typeof last === "object" && !Array.isArray(last) && "emit" in last ? this.extractEmitConfig(last) : void 0;
|
|
1087
|
+
try {
|
|
1088
|
+
if (action === "batch") {
|
|
1089
|
+
const operations = args[1];
|
|
1090
|
+
await this.handlers.persist("batch", "", { operations });
|
|
1091
|
+
this.emitSuccess(emitCfg, "success", operations);
|
|
1092
|
+
} else {
|
|
1093
|
+
const entityType = args[1];
|
|
1094
|
+
const data = args[2];
|
|
1095
|
+
await this.handlers.persist(action, entityType, data);
|
|
1096
|
+
this.emitSuccess(emitCfg, "success", data);
|
|
1097
|
+
}
|
|
1098
|
+
} catch (err) {
|
|
1099
|
+
this.emitFailure(emitCfg, err);
|
|
1100
|
+
throw err;
|
|
1020
1101
|
}
|
|
1021
1102
|
break;
|
|
1022
1103
|
}
|
|
@@ -1024,7 +1105,14 @@ var EffectExecutor = class {
|
|
|
1024
1105
|
const service = args[0];
|
|
1025
1106
|
const action = args[1];
|
|
1026
1107
|
const params = args[2];
|
|
1027
|
-
|
|
1108
|
+
const emitCfg = this.extractEmitConfig(args[3]);
|
|
1109
|
+
try {
|
|
1110
|
+
const result = await this.handlers.callService(service, action, params);
|
|
1111
|
+
this.emitSuccess(emitCfg, "success", result);
|
|
1112
|
+
} catch (err) {
|
|
1113
|
+
this.emitFailure(emitCfg, err);
|
|
1114
|
+
throw err;
|
|
1115
|
+
}
|
|
1028
1116
|
break;
|
|
1029
1117
|
}
|
|
1030
1118
|
case "fetch": {
|
|
@@ -1032,7 +1120,14 @@ var EffectExecutor = class {
|
|
|
1032
1120
|
const entityType = args[0];
|
|
1033
1121
|
const rawOpt = args[1];
|
|
1034
1122
|
const options = typeof rawOpt === "string" ? { id: rawOpt } : rawOpt;
|
|
1035
|
-
|
|
1123
|
+
const emitCfg = this.extractEmitConfig(rawOpt);
|
|
1124
|
+
try {
|
|
1125
|
+
const result = await this.handlers.fetch(entityType, options);
|
|
1126
|
+
this.emitSuccess(emitCfg, "success", result);
|
|
1127
|
+
} catch (err) {
|
|
1128
|
+
this.emitFailure(emitCfg, err);
|
|
1129
|
+
throw err;
|
|
1130
|
+
}
|
|
1036
1131
|
} else {
|
|
1037
1132
|
this.logUnsupported("fetch");
|
|
1038
1133
|
}
|
|
@@ -1043,12 +1138,20 @@ var EffectExecutor = class {
|
|
|
1043
1138
|
const refEntityType = args[0];
|
|
1044
1139
|
const rawRefOpt = args[1];
|
|
1045
1140
|
const refOptions = typeof rawRefOpt === "string" ? { id: rawRefOpt } : rawRefOpt;
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
this.
|
|
1141
|
+
const refEmitCfg = this.extractEmitConfig(rawRefOpt);
|
|
1142
|
+
try {
|
|
1143
|
+
let result = void 0;
|
|
1144
|
+
if (this.handlers.ref) {
|
|
1145
|
+
result = await this.handlers.ref(refEntityType, refOptions);
|
|
1146
|
+
} else if (this.handlers.fetch) {
|
|
1147
|
+
result = await this.handlers.fetch(refEntityType, refOptions);
|
|
1148
|
+
} else {
|
|
1149
|
+
this.logUnsupported("ref");
|
|
1150
|
+
}
|
|
1151
|
+
this.emitSuccess(refEmitCfg, "on_change", result);
|
|
1152
|
+
} catch (err) {
|
|
1153
|
+
this.emitFailure(refEmitCfg, err);
|
|
1154
|
+
throw err;
|
|
1052
1155
|
}
|
|
1053
1156
|
break;
|
|
1054
1157
|
}
|
|
@@ -1185,11 +1288,18 @@ var EffectExecutor = class {
|
|
|
1185
1288
|
break;
|
|
1186
1289
|
}
|
|
1187
1290
|
// OS trigger operators (server-side only)
|
|
1291
|
+
//
|
|
1292
|
+
// Each may carry `emit:` inside a trailing options object. The
|
|
1293
|
+
// executor extracts it and passes it to the handler so the
|
|
1294
|
+
// hardcoded fallback name (e.g. OS_CRON_FIRE) is replaced by the
|
|
1295
|
+
// author-configured event.
|
|
1188
1296
|
case "os/watch-files": {
|
|
1189
1297
|
if (this.handlers.osWatchFiles) {
|
|
1190
1298
|
const glob = args[0];
|
|
1191
|
-
const
|
|
1192
|
-
this.
|
|
1299
|
+
const rawOptions = args[1];
|
|
1300
|
+
const emitCfg = this.extractEmitConfig(rawOptions);
|
|
1301
|
+
const options = rawOptions ? { recursive: rawOptions.recursive, debounce: rawOptions.debounce } : {};
|
|
1302
|
+
this.handlers.osWatchFiles(glob, options, this.osEmit(emitCfg));
|
|
1193
1303
|
} else {
|
|
1194
1304
|
this.logUnsupported("os/watch-files");
|
|
1195
1305
|
}
|
|
@@ -1197,7 +1307,12 @@ var EffectExecutor = class {
|
|
|
1197
1307
|
}
|
|
1198
1308
|
case "os/watch-process": {
|
|
1199
1309
|
if (this.handlers.osWatchProcess) {
|
|
1200
|
-
this.
|
|
1310
|
+
const emitCfg = this.extractEmitConfig(args[2]);
|
|
1311
|
+
this.handlers.osWatchProcess(
|
|
1312
|
+
args[0],
|
|
1313
|
+
args[1],
|
|
1314
|
+
this.osEmit(emitCfg)
|
|
1315
|
+
);
|
|
1201
1316
|
} else {
|
|
1202
1317
|
this.logUnsupported("os/watch-process");
|
|
1203
1318
|
}
|
|
@@ -1205,7 +1320,12 @@ var EffectExecutor = class {
|
|
|
1205
1320
|
}
|
|
1206
1321
|
case "os/watch-port": {
|
|
1207
1322
|
if (this.handlers.osWatchPort) {
|
|
1208
|
-
this.
|
|
1323
|
+
const emitCfg = this.extractEmitConfig(args[2]);
|
|
1324
|
+
this.handlers.osWatchPort(
|
|
1325
|
+
args[0],
|
|
1326
|
+
args[1] ?? "tcp",
|
|
1327
|
+
this.osEmit(emitCfg)
|
|
1328
|
+
);
|
|
1209
1329
|
} else {
|
|
1210
1330
|
this.logUnsupported("os/watch-port");
|
|
1211
1331
|
}
|
|
@@ -1213,7 +1333,12 @@ var EffectExecutor = class {
|
|
|
1213
1333
|
}
|
|
1214
1334
|
case "os/watch-http": {
|
|
1215
1335
|
if (this.handlers.osWatchHttp) {
|
|
1216
|
-
this.
|
|
1336
|
+
const emitCfg = this.extractEmitConfig(args[2]);
|
|
1337
|
+
this.handlers.osWatchHttp(
|
|
1338
|
+
args[0],
|
|
1339
|
+
args[1],
|
|
1340
|
+
this.osEmit(emitCfg)
|
|
1341
|
+
);
|
|
1217
1342
|
} else {
|
|
1218
1343
|
this.logUnsupported("os/watch-http");
|
|
1219
1344
|
}
|
|
@@ -1221,7 +1346,8 @@ var EffectExecutor = class {
|
|
|
1221
1346
|
}
|
|
1222
1347
|
case "os/watch-cron": {
|
|
1223
1348
|
if (this.handlers.osWatchCron) {
|
|
1224
|
-
this.
|
|
1349
|
+
const emitCfg = this.extractEmitConfig(args[1]);
|
|
1350
|
+
this.handlers.osWatchCron(args[0], this.osEmit(emitCfg));
|
|
1225
1351
|
} else {
|
|
1226
1352
|
this.logUnsupported("os/watch-cron");
|
|
1227
1353
|
}
|
|
@@ -1229,7 +1355,8 @@ var EffectExecutor = class {
|
|
|
1229
1355
|
}
|
|
1230
1356
|
case "os/watch-signal": {
|
|
1231
1357
|
if (this.handlers.osWatchSignal) {
|
|
1232
|
-
this.
|
|
1358
|
+
const emitCfg = this.extractEmitConfig(args[1]);
|
|
1359
|
+
this.handlers.osWatchSignal(args[0], this.osEmit(emitCfg));
|
|
1233
1360
|
} else {
|
|
1234
1361
|
this.logUnsupported("os/watch-signal");
|
|
1235
1362
|
}
|
|
@@ -1237,7 +1364,8 @@ var EffectExecutor = class {
|
|
|
1237
1364
|
}
|
|
1238
1365
|
case "os/watch-env": {
|
|
1239
1366
|
if (this.handlers.osWatchEnv) {
|
|
1240
|
-
this.
|
|
1367
|
+
const emitCfg = this.extractEmitConfig(args[1]);
|
|
1368
|
+
this.handlers.osWatchEnv(args[0], this.osEmit(emitCfg));
|
|
1241
1369
|
} else {
|
|
1242
1370
|
this.logUnsupported("os/watch-env");
|
|
1243
1371
|
}
|
|
@@ -2559,5 +2687,5 @@ function parseNamespacedEvent(eventName) {
|
|
|
2559
2687
|
}
|
|
2560
2688
|
|
|
2561
2689
|
export { EffectExecutor, EventBus, HANDLER_MANIFEST, StateMachineManager, containsBindings, createContextFromBindings, createInitialTraitState, createTestExecutor, createUnifiedLoader, extractBindings, findInitialState, findTransition, getIsolatedCollectionName, getNamespacedEvent, interpolateProps, interpolateValue, isNamespacedEvent, normalizeEventKey, parseNamespacedEvent, preprocessSchema, processEvent };
|
|
2562
|
-
//# sourceMappingURL=chunk-
|
|
2563
|
-
//# sourceMappingURL=chunk-
|
|
2690
|
+
//# sourceMappingURL=chunk-PXASRZKG.js.map
|
|
2691
|
+
//# sourceMappingURL=chunk-PXASRZKG.js.map
|