@almadar/runtime 6.18.0 → 6.20.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.
@@ -122,6 +122,92 @@ var EventBus = class {
122
122
  return this.listeners.get(type)?.size ?? 0;
123
123
  }
124
124
  };
125
+
126
+ // src/TickScheduler.ts
127
+ var EVERY_PASS = 0;
128
+ var TickScheduler = class {
129
+ ticks = /* @__PURE__ */ new Map();
130
+ nextId = 1;
131
+ running = false;
132
+ frameHandle = null;
133
+ hasRaf;
134
+ constructor() {
135
+ this.hasRaf = typeof requestAnimationFrame === "function" && typeof cancelAnimationFrame === "function";
136
+ }
137
+ /**
138
+ * Register a tick. `intervalMs <= 0` means "every pass" (a frame-interval
139
+ * tick, matching LOLO's `interval: "frame"`). Returns a handle to stop
140
+ * just this tick.
141
+ */
142
+ add(intervalMs, onDue) {
143
+ const id = this.nextId++;
144
+ this.ticks.set(id, {
145
+ intervalMs: intervalMs > 0 ? intervalMs : EVERY_PASS,
146
+ accumulatedMs: 0,
147
+ lastTimestamp: null,
148
+ onDue
149
+ });
150
+ this.ensureRunning();
151
+ return {
152
+ stop: () => {
153
+ this.ticks.delete(id);
154
+ this.maybeStop();
155
+ }
156
+ };
157
+ }
158
+ /** Stop every tick and the shared loop. */
159
+ stopAll() {
160
+ this.ticks.clear();
161
+ this.maybeStop();
162
+ }
163
+ ensureRunning() {
164
+ if (this.running) return;
165
+ this.running = true;
166
+ if (this.hasRaf) {
167
+ const loop = (timestamp) => {
168
+ if (!this.running) return;
169
+ this.advance(timestamp);
170
+ this.frameHandle = requestAnimationFrame(loop);
171
+ };
172
+ this.frameHandle = requestAnimationFrame(loop);
173
+ } else {
174
+ this.frameHandle = setInterval(() => this.advance(Date.now()), 16);
175
+ }
176
+ }
177
+ maybeStop() {
178
+ if (this.ticks.size > 0 || !this.running) return;
179
+ this.running = false;
180
+ if (this.frameHandle !== null) {
181
+ if (this.hasRaf) {
182
+ cancelAnimationFrame(this.frameHandle);
183
+ } else {
184
+ clearInterval(this.frameHandle);
185
+ }
186
+ this.frameHandle = null;
187
+ }
188
+ }
189
+ advance(timestamp) {
190
+ for (const tick of this.ticks.values()) {
191
+ if (tick.intervalMs <= EVERY_PASS) {
192
+ tick.onDue();
193
+ continue;
194
+ }
195
+ if (tick.lastTimestamp === null) {
196
+ tick.lastTimestamp = timestamp;
197
+ continue;
198
+ }
199
+ tick.accumulatedMs += timestamp - tick.lastTimestamp;
200
+ tick.lastTimestamp = timestamp;
201
+ while (tick.accumulatedMs >= tick.intervalMs) {
202
+ tick.accumulatedMs -= tick.intervalMs;
203
+ tick.onDue();
204
+ }
205
+ }
206
+ }
207
+ };
208
+ function createTickScheduler() {
209
+ return new TickScheduler();
210
+ }
125
211
  var bindLog = createLogger("almadar:runtime:bindings");
126
212
  var renderLog = createLogger("almadar:runtime:render-ui");
127
213
  var CLIENT_ONLY_BINDING_ROOTS = /* @__PURE__ */ new Set(["trait"]);
@@ -3722,6 +3808,6 @@ var InMemoryPersistence = class {
3722
3808
  }
3723
3809
  };
3724
3810
 
3725
- export { EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, MockPersistenceAdapter, StateMachineManager, buildEmitsFromTraits, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, containsBindings, createContextFromBindings, createInitialTraitState, createMockPersistence, createTestExecutor, createUnifiedLoader, extractBindings, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, interpolateProps, interpolateValue, isBrowser, isElectron, isNamespacedEvent, isNode, normalizeEventKey, parseNamespacedEvent, preprocessSchema, processEvent, validateEventPayload, validatePayloadShapes };
3726
- //# sourceMappingURL=chunk-G2VW5WJZ.js.map
3727
- //# sourceMappingURL=chunk-G2VW5WJZ.js.map
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-JZ4IDIUU.js.map
3813
+ //# sourceMappingURL=chunk-JZ4IDIUU.js.map