@almadar/runtime 6.19.0 → 6.21.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-TewGACFH.d.ts → OrbitalServerRuntime-CO0rEx3p.d.ts} +0 -5
- package/dist/OrbitalServerRuntime.d.ts +1 -1
- package/dist/OrbitalServerRuntime.js +19 -28
- package/dist/OrbitalServerRuntime.js.map +1 -1
- package/dist/{chunk-JZ4IDIUU.js → chunk-53VRCHPK.js} +81 -4
- package/dist/chunk-53VRCHPK.js.map +1 -0
- package/dist/chunk-U4PL237A.js +51 -0
- package/dist/chunk-U4PL237A.js.map +1 -0
- package/dist/createOsHandlers.js +2 -36
- package/dist/createOsHandlers.js.map +1 -1
- package/dist/index.d.ts +56 -3
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-JZ4IDIUU.js.map +0 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { parseCron, cronMinuteKey, cronMatches } from './chunk-U4PL237A.js';
|
|
1
2
|
import { createLogger } from '@almadar/logger';
|
|
2
3
|
import { resolveBinding, evaluate, createMinimalContext, evaluateGuard } from '@almadar/evaluator';
|
|
3
4
|
export { createMinimalContext } from '@almadar/evaluator';
|
|
@@ -5,7 +6,6 @@ import { isKnownStdOperator } from '@almadar/std/registry';
|
|
|
5
6
|
import { faker } from '@faker-js/faker';
|
|
6
7
|
import { OrbitalSchemaSchema, isInlineTrait, isEntityCall, isEntityReference, parseEntityRef, parseImportedTraitRef, isPageReference, isPageReferenceString, isPageReferenceObject, parsePageRef } from '@almadar/core';
|
|
7
8
|
|
|
8
|
-
// src/EventBus.ts
|
|
9
9
|
var log = createLogger("almadar:runtime:eventbus");
|
|
10
10
|
var EventBus = class {
|
|
11
11
|
listeners = /* @__PURE__ */ new Map();
|
|
@@ -125,6 +125,7 @@ var EventBus = class {
|
|
|
125
125
|
|
|
126
126
|
// src/TickScheduler.ts
|
|
127
127
|
var EVERY_PASS = 0;
|
|
128
|
+
var CRON_CHECK_INTERVAL_MS = 1e3;
|
|
128
129
|
var TickScheduler = class {
|
|
129
130
|
ticks = /* @__PURE__ */ new Map();
|
|
130
131
|
nextId = 1;
|
|
@@ -142,6 +143,7 @@ var TickScheduler = class {
|
|
|
142
143
|
add(intervalMs, onDue) {
|
|
143
144
|
const id = this.nextId++;
|
|
144
145
|
this.ticks.set(id, {
|
|
146
|
+
kind: "interval",
|
|
145
147
|
intervalMs: intervalMs > 0 ? intervalMs : EVERY_PASS,
|
|
146
148
|
accumulatedMs: 0,
|
|
147
149
|
lastTimestamp: null,
|
|
@@ -155,6 +157,33 @@ var TickScheduler = class {
|
|
|
155
157
|
}
|
|
156
158
|
};
|
|
157
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Register a cron-scheduled tick (`ticks { ... every "0 9 * * *" }`).
|
|
162
|
+
* Fires at most once per matching calendar minute — the same dedup shape
|
|
163
|
+
* `os/watch-cron` uses. Throws if `expression` isn't a valid 5-field cron
|
|
164
|
+
* string; callers on a path the compiler has already validated (e.g.
|
|
165
|
+
* generated code) won't hit this, but a raw runtime value might.
|
|
166
|
+
*/
|
|
167
|
+
addCron(expression, onDue) {
|
|
168
|
+
const fields = parseCron(expression);
|
|
169
|
+
const id = this.nextId++;
|
|
170
|
+
this.ticks.set(id, {
|
|
171
|
+
kind: "cron",
|
|
172
|
+
fields,
|
|
173
|
+
accumulatedMs: CRON_CHECK_INTERVAL_MS,
|
|
174
|
+
// check on the first pass, not after a full second
|
|
175
|
+
lastTimestamp: null,
|
|
176
|
+
lastFiredMinuteKey: -1,
|
|
177
|
+
onDue
|
|
178
|
+
});
|
|
179
|
+
this.ensureRunning();
|
|
180
|
+
return {
|
|
181
|
+
stop: () => {
|
|
182
|
+
this.ticks.delete(id);
|
|
183
|
+
this.maybeStop();
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
}
|
|
158
187
|
/** Stop every tick and the shared loop. */
|
|
159
188
|
stopAll() {
|
|
160
189
|
this.ticks.clear();
|
|
@@ -188,6 +217,10 @@ var TickScheduler = class {
|
|
|
188
217
|
}
|
|
189
218
|
advance(timestamp) {
|
|
190
219
|
for (const tick of this.ticks.values()) {
|
|
220
|
+
if (tick.kind === "cron") {
|
|
221
|
+
this.advanceCron(tick, timestamp);
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
191
224
|
if (tick.intervalMs <= EVERY_PASS) {
|
|
192
225
|
tick.onDue();
|
|
193
226
|
continue;
|
|
@@ -204,10 +237,54 @@ var TickScheduler = class {
|
|
|
204
237
|
}
|
|
205
238
|
}
|
|
206
239
|
}
|
|
240
|
+
/** Cron ticks check calendar-match at most once a second, deduped per matching minute. */
|
|
241
|
+
advanceCron(tick, timestamp) {
|
|
242
|
+
if (tick.lastTimestamp === null) {
|
|
243
|
+
tick.lastTimestamp = timestamp;
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
tick.accumulatedMs += timestamp - tick.lastTimestamp;
|
|
247
|
+
tick.lastTimestamp = timestamp;
|
|
248
|
+
if (tick.accumulatedMs < CRON_CHECK_INTERVAL_MS) return;
|
|
249
|
+
tick.accumulatedMs = 0;
|
|
250
|
+
const now = /* @__PURE__ */ new Date();
|
|
251
|
+
const minuteKey = cronMinuteKey(now);
|
|
252
|
+
if (minuteKey !== tick.lastFiredMinuteKey && cronMatches(tick.fields, now)) {
|
|
253
|
+
tick.lastFiredMinuteKey = minuteKey;
|
|
254
|
+
tick.onDue();
|
|
255
|
+
}
|
|
256
|
+
}
|
|
207
257
|
};
|
|
208
258
|
function createTickScheduler() {
|
|
209
259
|
return new TickScheduler();
|
|
210
260
|
}
|
|
261
|
+
|
|
262
|
+
// src/duration.ts
|
|
263
|
+
function parseDurationString(interval) {
|
|
264
|
+
const match = interval.match(/^(\d+)(ms|s|m|h)?$/);
|
|
265
|
+
if (!match) {
|
|
266
|
+
throw new Error(
|
|
267
|
+
`Invalid duration '${interval}': expected a shape like '5ms'/'5s'/'1m'/'1h'`
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
const value = parseInt(match[1], 10);
|
|
271
|
+
const unit = match[2] || "ms";
|
|
272
|
+
switch (unit) {
|
|
273
|
+
case "ms":
|
|
274
|
+
return value;
|
|
275
|
+
case "s":
|
|
276
|
+
return value * 1e3;
|
|
277
|
+
case "m":
|
|
278
|
+
return value * 60 * 1e3;
|
|
279
|
+
case "h":
|
|
280
|
+
return value * 60 * 60 * 1e3;
|
|
281
|
+
default:
|
|
282
|
+
return value;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
function isValidDurationString(interval) {
|
|
286
|
+
return /^(\d+)(ms|s|m|h)?$/.test(interval);
|
|
287
|
+
}
|
|
211
288
|
var bindLog = createLogger("almadar:runtime:bindings");
|
|
212
289
|
var renderLog = createLogger("almadar:runtime:render-ui");
|
|
213
290
|
var CLIENT_ONLY_BINDING_ROOTS = /* @__PURE__ */ new Set(["trait"]);
|
|
@@ -3808,6 +3885,6 @@ var InMemoryPersistence = class {
|
|
|
3808
3885
|
}
|
|
3809
3886
|
};
|
|
3810
3887
|
|
|
3811
|
-
export { EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, MockPersistenceAdapter, StateMachineManager, TickScheduler, buildEmitsFromTraits, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, containsBindings, createContextFromBindings, createInitialTraitState, createMockPersistence, createTestExecutor, createTickScheduler, createUnifiedLoader, extractBindings, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, interpolateProps, interpolateValue, isBrowser, isElectron, isNamespacedEvent, isNode, normalizeEventKey, parseNamespacedEvent, preprocessSchema, processEvent, validateEventPayload, validatePayloadShapes };
|
|
3812
|
-
//# sourceMappingURL=chunk-
|
|
3813
|
-
//# sourceMappingURL=chunk-
|
|
3888
|
+
export { EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, MockPersistenceAdapter, StateMachineManager, TickScheduler, buildEmitsFromTraits, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, containsBindings, createContextFromBindings, createInitialTraitState, createMockPersistence, createTestExecutor, createTickScheduler, createUnifiedLoader, extractBindings, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, interpolateProps, interpolateValue, isBrowser, isElectron, isNamespacedEvent, isNode, isValidDurationString, normalizeEventKey, parseDurationString, parseNamespacedEvent, preprocessSchema, processEvent, validateEventPayload, validatePayloadShapes };
|
|
3889
|
+
//# sourceMappingURL=chunk-53VRCHPK.js.map
|
|
3890
|
+
//# sourceMappingURL=chunk-53VRCHPK.js.map
|