kitchen-simulator 5.10.8-react.18 → 5.10.10-react.18

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.
@@ -43,7 +43,6 @@ var LiteKitchenConfigurator = /*#__PURE__*/function (_Component) {
43
43
  var _this;
44
44
  _classCallCheck(this, LiteKitchenConfigurator);
45
45
  _this = _callSuper(this, LiteKitchenConfigurator, [props]);
46
- _this._catalogInitStarted = false;
47
46
  _this.state = {
48
47
  savePopupVisible: false,
49
48
  quotePopupVisible: false,
@@ -290,33 +289,33 @@ var LiteKitchenConfigurator = /*#__PURE__*/function (_Component) {
290
289
  if (el !== null && el !== void 0 && (_el$parentElement0 = el.parentElement) !== null && _el$parentElement0 !== void 0 && _el$parentElement0.parentElement) el.parentElement.parentElement.style.zIndex = 6;
291
290
  }
292
291
  }, {
293
- key: "ensureCatalogReady",
294
- value: function ensureCatalogReady() {
292
+ key: "componentDidMount",
293
+ value: function componentDidMount() {
295
294
  var _extractedState$getIn;
295
+ window.forRedo = [];
296
296
  var _this$props = this.props,
297
297
  catalog = _this$props.catalog,
298
298
  extractedState = _this$props.extractedState,
299
299
  projectActions = _this$props.projectActions;
300
- var ready = extractedState === null || extractedState === void 0 || (_extractedState$getIn = extractedState.getIn) === null || _extractedState$getIn === void 0 ? void 0 : _extractedState$getIn.call(extractedState, ['catalog', 'ready']);
301
- if (ready) return;
302
- if (this._catalogInitStarted) return; // ✅ prevent repeated init storms
303
- this._catalogInitStarted = true;
304
- projectActions.initCatalog(catalog);
305
- }
306
- }, {
307
- key: "componentDidMount",
308
- value: function componentDidMount() {
309
- window.forRedo = [];
310
- if (this.props.externalEvent) handleExternalEvent(this.props);
311
- this.ensureCatalogReady();
300
+ var catalogReady = extractedState === null || extractedState === void 0 || (_extractedState$getIn = extractedState.getIn) === null || _extractedState$getIn === void 0 ? void 0 : _extractedState$getIn.call(extractedState, ['catalog', 'ready']);
301
+ if (!catalogReady) projectActions.initCatalog(catalog);
312
302
  }
313
303
  }, {
314
304
  key: "componentDidUpdate",
315
305
  value: function componentDidUpdate(prevProps) {
316
- if (prevProps.externalEvent !== this.props.externalEvent) {
306
+ var _extractedState$getIn2;
307
+ var _this$props2 = this.props,
308
+ externalEvent = _this$props2.externalEvent,
309
+ extractedState = _this$props2.extractedState,
310
+ projectActions = _this$props2.projectActions,
311
+ catalog = _this$props2.catalog;
312
+
313
+ // same behavior: handle external event when it changes
314
+ if (prevProps.externalEvent !== externalEvent) {
317
315
  handleExternalEvent(this.props);
318
316
  }
319
- this.ensureCatalogReady();
317
+ var catalogReady = extractedState === null || extractedState === void 0 || (_extractedState$getIn2 = extractedState.getIn) === null || _extractedState$getIn2 === void 0 ? void 0 : _extractedState$getIn2.call(extractedState, ['catalog', 'ready']);
318
+ if (!catalogReady) projectActions.initCatalog(catalog);
320
319
  }
321
320
  }, {
322
321
  key: "isProjectEmpty",
@@ -367,11 +366,11 @@ var LiteKitchenConfigurator = /*#__PURE__*/function (_Component) {
367
366
  key: "render",
368
367
  value: function render() {
369
368
  var _this2 = this;
370
- var _this$props2 = this.props,
371
- width = _this$props2.width,
372
- height = _this$props2.height,
373
- extractedState = _this$props2.extractedState,
374
- props = _objectWithoutProperties(_this$props2, _excluded);
369
+ var _this$props3 = this.props,
370
+ width = _this$props3.width,
371
+ height = _this$props3.height,
372
+ extractedState = _this$props3.extractedState,
373
+ props = _objectWithoutProperties(_this$props3, _excluded);
375
374
  var _this$state = this.state,
376
375
  savePopupVisible = _this$state.savePopupVisible,
377
376
  quotePopupVisible = _this$state.quotePopupVisible,
package/es/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
1
2
  import _extends from "@babel/runtime/helpers/esm/extends";
2
3
  import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
3
4
  import _createClass from "@babel/runtime/helpers/esm/createClass";
@@ -5,6 +6,9 @@ import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConst
5
6
  import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
6
7
  import _inherits from "@babel/runtime/helpers/esm/inherits";
7
8
  import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
9
+ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
10
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
11
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8
12
  function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
9
13
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
10
14
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
@@ -17,10 +21,54 @@ import LiteRenderer from "./LiteRenderer";
17
21
  import { createRoot } from 'react-dom/client';
18
22
  var ROOT_KEY = '__kitchenSimulatorRoot__';
19
23
  var API_KEY = '__kitchenSimulatorApi__';
20
- function nextFrame() {
21
- return new Promise(function (resolve) {
22
- return requestAnimationFrame(resolve);
23
- });
24
+ function makeLogger(getEnabled) {
25
+ var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '[kitchen-simulator]';
26
+ var now = function now() {
27
+ return (typeof performance !== 'undefined' && performance.now ? performance.now() : Date.now()).toFixed(1);
28
+ };
29
+ var safe = function safe(v) {
30
+ try {
31
+ if (v == null) return v;
32
+ if (typeof v === 'string') return v;
33
+ if (typeof v === 'number' || typeof v === 'boolean') return v;
34
+ return JSON.stringify(v, function (k, val) {
35
+ if (k === 'children' || k === 'parent') return '[omitted]';
36
+ if (typeof val === 'function') return '[fn]';
37
+ return val;
38
+ });
39
+ } catch (_unused) {
40
+ return '[unserializable]';
41
+ }
42
+ };
43
+ var log = function log() {
44
+ var _console;
45
+ if (!getEnabled()) return;
46
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
47
+ args[_key] = arguments[_key];
48
+ }
49
+ (_console = console).log.apply(_console, ["".concat(prefix, " ").concat(now(), "ms")].concat(_toConsumableArray(args.map(safe))));
50
+ };
51
+ var warn = function warn() {
52
+ var _console2;
53
+ if (!getEnabled()) return;
54
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
55
+ args[_key2] = arguments[_key2];
56
+ }
57
+ (_console2 = console).warn.apply(_console2, ["".concat(prefix, " ").concat(now(), "ms")].concat(_toConsumableArray(args.map(safe))));
58
+ };
59
+ var error = function error() {
60
+ var _console3;
61
+ if (!getEnabled()) return;
62
+ for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
63
+ args[_key3] = arguments[_key3];
64
+ }
65
+ (_console3 = console).error.apply(_console3, ["".concat(prefix, " ").concat(now(), "ms")].concat(_toConsumableArray(args.map(safe))));
66
+ };
67
+ return {
68
+ log: log,
69
+ warn: warn,
70
+ error: error
71
+ };
24
72
  }
25
73
 
26
74
  // DIY-714 [Temp Fix] Rewrite API URLs
@@ -40,6 +88,7 @@ Three.TextureLoader.prototype.load = function (url, onLoad, onProgress, onError)
40
88
  * Ref-counted global install so multiple instances don't clobber each other.
41
89
  */
42
90
  function installGltfTracker() {
91
+ var debug = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
43
92
  if (typeof window === 'undefined') {
44
93
  var _subscribe = function _subscribe() {
45
94
  return function () {};
@@ -70,6 +119,7 @@ function installGltfTracker() {
70
119
  };
71
120
  }
72
121
  var GLOBAL_KEY = '__kitchenSimulatorGltfTracker__';
122
+ var TRACKER_DEBUG_KEY = '__kitchenSimulatorDebug__';
73
123
  if (!window[GLOBAL_KEY]) {
74
124
  window[GLOBAL_KEY] = {
75
125
  refCount: 0,
@@ -82,13 +132,20 @@ function installGltfTracker() {
82
132
  };
83
133
  }
84
134
  var g = window[GLOBAL_KEY];
135
+ var isDebug = function isDebug() {
136
+ return !!debug || !!window[TRACKER_DEBUG_KEY];
137
+ };
138
+ var _makeLogger = makeLogger(isDebug, '[kitchen-simulator:gltf]'),
139
+ log = _makeLogger.log,
140
+ warn = _makeLogger.warn,
141
+ error = _makeLogger.error;
85
142
  var is3dAssetUrl = function is3dAssetUrl(url) {
86
143
  try {
87
144
  var _url$toString, _url$toString2;
88
145
  var s = typeof url === 'string' ? url : (_url$toString = url === null || url === void 0 || (_url$toString2 = url.toString) === null || _url$toString2 === void 0 ? void 0 : _url$toString2.call(url)) !== null && _url$toString !== void 0 ? _url$toString : '';
89
- var u = s.toLowerCase().split('?')[0]; // ignore cache params
146
+ var u = s.toLowerCase().split('?')[0];
90
147
  return u.endsWith('.gltf') || u.endsWith('.glb') || u.endsWith('.bin') || u.endsWith('.ktx2') || u.endsWith('.hdr') || u.endsWith('.exr') || u.endsWith('.png') || u.endsWith('.jpg') || u.endsWith('.jpeg') || u.endsWith('.webp');
91
- } catch (_unused) {
148
+ } catch (_unused2) {
92
149
  return false;
93
150
  }
94
151
  };
@@ -108,7 +165,7 @@ function installGltfTracker() {
108
165
  };
109
166
  var subscribe = function subscribe(fn) {
110
167
  g.listeners.add(fn);
111
- fn(g.inFlight); // sync emit on subscribe
168
+ fn(g.inFlight);
112
169
  return function () {
113
170
  return g.listeners["delete"](fn);
114
171
  };
@@ -116,8 +173,9 @@ function installGltfTracker() {
116
173
  var installIfNeeded = function installIfNeeded() {
117
174
  var _XHR$prototype, _XHR$prototype2;
118
175
  if (g.installed) return;
176
+ log('Installing GLTF tracker hooks');
119
177
 
120
- // ---- XHR hook ----
178
+ // XHR hook
121
179
  var XHR = window.XMLHttpRequest;
122
180
  if (XHR !== null && XHR !== void 0 && (_XHR$prototype = XHR.prototype) !== null && _XHR$prototype !== void 0 && _XHR$prototype.open && XHR !== null && XHR !== void 0 && (_XHR$prototype2 = XHR.prototype) !== null && _XHR$prototype2 !== void 0 && _XHR$prototype2.send) {
123
181
  g.originalOpen = XHR.prototype.open;
@@ -125,8 +183,12 @@ function installGltfTracker() {
125
183
  XHR.prototype.open = function (method, url) {
126
184
  var _g$originalOpen;
127
185
  this.__is3dAssetRequest = is3dAssetUrl(url);
128
- for (var _len = arguments.length, rest = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
129
- rest[_key - 2] = arguments[_key];
186
+ if (this.__is3dAssetRequest) log('XHR open (3D asset)', {
187
+ method: method,
188
+ url: url
189
+ });
190
+ for (var _len4 = arguments.length, rest = new Array(_len4 > 2 ? _len4 - 2 : 0), _key4 = 2; _key4 < _len4; _key4++) {
191
+ rest[_key4 - 2] = arguments[_key4];
130
192
  }
131
193
  return (_g$originalOpen = g.originalOpen).call.apply(_g$originalOpen, [this, method, url].concat(rest));
132
194
  };
@@ -134,41 +196,57 @@ function installGltfTracker() {
134
196
  var _this = this;
135
197
  if (this.__is3dAssetRequest) {
136
198
  g.inFlight += 1;
199
+ log('XHR send -> inFlight++', g.inFlight);
137
200
  notify();
138
201
  var _done = function done() {
139
202
  g.inFlight -= 1;
140
203
  if (g.inFlight < 0) g.inFlight = 0;
204
+ log('XHR done -> inFlight--', g.inFlight);
141
205
  notify();
142
206
  _this.removeEventListener('loadend', _done);
207
+ _this.removeEventListener('error', _done);
208
+ _this.removeEventListener('abort', _done);
209
+ _this.removeEventListener('timeout', _done);
143
210
  };
144
211
  this.addEventListener('loadend', _done);
212
+ this.addEventListener('error', _done);
213
+ this.addEventListener('abort', _done);
214
+ this.addEventListener('timeout', _done);
145
215
  }
146
- for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
147
- args[_key2] = arguments[_key2];
216
+ for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
217
+ args[_key5] = arguments[_key5];
148
218
  }
149
219
  return g.originalSend.apply(this, args);
150
220
  };
221
+ } else {
222
+ warn('XHR hooks not installed (missing open/send)');
151
223
  }
152
224
 
153
- // ---- fetch hook ----
225
+ // fetch hook
154
226
  g.originalFetch = window.fetch;
155
227
  if (typeof g.originalFetch === 'function') {
156
228
  window.fetch = /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
157
- var _len3,
229
+ var _input;
230
+ var _len6,
158
231
  args,
159
- _key3,
232
+ _key6,
160
233
  input,
161
234
  init,
162
235
  newUrl,
163
236
  track,
164
- _args2 = arguments;
237
+ _input2,
238
+ res,
239
+ _input3,
240
+ _e$message,
241
+ _args2 = arguments,
242
+ _t;
165
243
  return _regeneratorRuntime.wrap(function (_context2) {
166
244
  while (1) switch (_context2.prev = _context2.next) {
167
245
  case 0:
168
- for (_len3 = _args2.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
169
- args[_key3] = _args2[_key3];
246
+ for (_len6 = _args2.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
247
+ args[_key6] = _args2[_key6];
170
248
  }
171
- input = args[0], init = args[1]; // DIY-714 [Temp Fix] Rewrite API URLs
249
+ input = args[0], init = args[1];
172
250
  if (typeof input === 'string') {
173
251
  input = rewriteApiUrl(input);
174
252
  } else if (input instanceof Request) {
@@ -183,55 +261,92 @@ function installGltfTracker() {
183
261
  return _context2.abrupt("return", g.originalFetch.call(this, input, init));
184
262
  case 1:
185
263
  g.inFlight += 1;
264
+ log('fetch (3D asset) -> inFlight++', g.inFlight, {
265
+ url: typeof input === 'string' ? input : (_input = input) === null || _input === void 0 ? void 0 : _input.url
266
+ });
186
267
  notify();
187
268
  _context2.prev = 2;
188
269
  _context2.next = 3;
189
270
  return g.originalFetch.call(this, input, init);
190
271
  case 3:
191
- return _context2.abrupt("return", _context2.sent);
272
+ res = _context2.sent;
273
+ log('fetch response (3D asset)', {
274
+ url: typeof input === 'string' ? input : (_input2 = input) === null || _input2 === void 0 ? void 0 : _input2.url,
275
+ ok: res === null || res === void 0 ? void 0 : res.ok,
276
+ status: res === null || res === void 0 ? void 0 : res.status
277
+ });
278
+ return _context2.abrupt("return", res);
192
279
  case 4:
193
280
  _context2.prev = 4;
281
+ _t = _context2["catch"](2);
282
+ error('fetch error (3D asset)', {
283
+ url: typeof input === 'string' ? input : (_input3 = input) === null || _input3 === void 0 ? void 0 : _input3.url,
284
+ error: (_e$message = _t === null || _t === void 0 ? void 0 : _t.message) !== null && _e$message !== void 0 ? _e$message : _t
285
+ });
286
+ throw _t;
287
+ case 5:
288
+ _context2.prev = 5;
194
289
  g.inFlight -= 1;
195
290
  if (g.inFlight < 0) g.inFlight = 0;
291
+ log('fetch finally -> inFlight--', g.inFlight);
196
292
  notify();
197
- return _context2.finish(4);
198
- case 5:
293
+ return _context2.finish(5);
294
+ case 6:
199
295
  case "end":
200
296
  return _context2.stop();
201
297
  }
202
- }, _callee2, this, [[2,, 4, 5]]);
298
+ }, _callee2, this, [[2, 4, 5, 6]]);
203
299
  }));
300
+ } else {
301
+ warn('fetch hook not installed (window.fetch not a function)');
204
302
  }
205
303
  g.installed = true;
206
304
  };
207
-
208
- // “No grace” but stable: idle must remain idle for 2 RAF frames
305
+ function nextFrame() {
306
+ return _nextFrame.apply(this, arguments);
307
+ }
308
+ function _nextFrame() {
309
+ _nextFrame = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5() {
310
+ return _regeneratorRuntime.wrap(function (_context5) {
311
+ while (1) switch (_context5.prev = _context5.next) {
312
+ case 0:
313
+ return _context5.abrupt("return", new Promise(function (resolve) {
314
+ return requestAnimationFrame(resolve);
315
+ }));
316
+ case 1:
317
+ case "end":
318
+ return _context5.stop();
319
+ }
320
+ }, _callee5);
321
+ }));
322
+ return _nextFrame.apply(this, arguments);
323
+ }
209
324
  function waitStableIdle2Frames() {
210
325
  return _waitStableIdle2Frames.apply(this, arguments);
211
326
  }
212
327
  function _waitStableIdle2Frames() {
213
- _waitStableIdle2Frames = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5() {
214
- return _regeneratorRuntime.wrap(function (_context5) {
215
- while (1) switch (_context5.prev = _context5.next) {
328
+ _waitStableIdle2Frames = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee6() {
329
+ return _regeneratorRuntime.wrap(function (_context6) {
330
+ while (1) switch (_context6.prev = _context6.next) {
216
331
  case 0:
217
- _context5.next = 1;
332
+ _context6.next = 1;
218
333
  return nextFrame();
219
334
  case 1:
220
335
  if (!(g.inFlight !== 0)) {
221
- _context5.next = 2;
336
+ _context6.next = 2;
222
337
  break;
223
338
  }
224
- return _context5.abrupt("return", false);
339
+ return _context6.abrupt("return", false);
225
340
  case 2:
226
- _context5.next = 3;
341
+ _context6.next = 3;
227
342
  return nextFrame();
228
343
  case 3:
229
- return _context5.abrupt("return", g.inFlight === 0);
344
+ return _context6.abrupt("return", g.inFlight === 0);
230
345
  case 4:
231
346
  case "end":
232
- return _context5.stop();
347
+ return _context6.stop();
233
348
  }
234
- }, _callee5);
349
+ }, _callee6);
235
350
  }));
236
351
  return _waitStableIdle2Frames.apply(this, arguments);
237
352
  }
@@ -240,13 +355,15 @@ function installGltfTracker() {
240
355
  var _ref3,
241
356
  _ref3$timeoutMs,
242
357
  timeoutMs,
243
- start,
244
358
  _args4 = arguments;
245
359
  return _regeneratorRuntime.wrap(function (_context4) {
246
360
  while (1) switch (_context4.prev = _context4.next) {
247
361
  case 0:
248
362
  _ref3 = _args4.length > 0 && _args4[0] !== undefined ? _args4[0] : {}, _ref3$timeoutMs = _ref3.timeoutMs, timeoutMs = _ref3$timeoutMs === void 0 ? 30000 : _ref3$timeoutMs;
249
- start = Date.now();
363
+ log('waitForIdle start', {
364
+ timeoutMs: timeoutMs,
365
+ inFlight: g.inFlight
366
+ });
250
367
  _context4.next = 1;
251
368
  return waitStableIdle2Frames();
252
369
  case 1:
@@ -254,42 +371,57 @@ function installGltfTracker() {
254
371
  _context4.next = 2;
255
372
  break;
256
373
  }
374
+ log('waitForIdle fast-path resolved');
257
375
  return _context4.abrupt("return", true);
258
376
  case 2:
259
377
  return _context4.abrupt("return", new Promise(function (resolve, reject) {
260
378
  var unsub = null;
379
+ var finished = false;
380
+ var finishOk = function finishOk() {
381
+ if (finished) return;
382
+ finished = true;
383
+ if (unsub) unsub();
384
+ clearTimeout(timer);
385
+ log('waitForIdle resolved');
386
+ resolve(true);
387
+ };
388
+ var finishErr = function finishErr(err) {
389
+ var _err$message;
390
+ if (finished) return;
391
+ finished = true;
392
+ if (unsub) unsub();
393
+ clearTimeout(timer);
394
+ error('waitForIdle timeout/reject', (_err$message = err === null || err === void 0 ? void 0 : err.message) !== null && _err$message !== void 0 ? _err$message : err);
395
+ reject(err);
396
+ };
397
+ var timer = setTimeout(function () {
398
+ finishErr(new Error('3D assets did not become idle within timeout'));
399
+ }, timeoutMs);
261
400
  var onChange = /*#__PURE__*/function () {
262
401
  var _ref4 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(count) {
263
402
  var stable;
264
403
  return _regeneratorRuntime.wrap(function (_context3) {
265
404
  while (1) switch (_context3.prev = _context3.next) {
266
405
  case 0:
267
- if (!(count !== 0)) {
406
+ if (!finished) {
268
407
  _context3.next = 1;
269
408
  break;
270
409
  }
271
- if (Date.now() - start > timeoutMs) {
272
- if (unsub) unsub();
273
- reject(new Error('3D assets did not become idle within timeout'));
274
- }
275
410
  return _context3.abrupt("return");
276
411
  case 1:
277
- _context3.next = 2;
278
- return waitStableIdle2Frames();
279
- case 2:
280
- stable = _context3.sent;
281
- if (!stable) {
282
- _context3.next = 3;
412
+ log('waitForIdle inFlight change', count);
413
+ if (!(count !== 0)) {
414
+ _context3.next = 2;
283
415
  break;
284
416
  }
285
- if (unsub) unsub();
286
- resolve(true);
287
417
  return _context3.abrupt("return");
418
+ case 2:
419
+ _context3.next = 3;
420
+ return waitStableIdle2Frames();
288
421
  case 3:
289
- if (Date.now() - start > timeoutMs) {
290
- if (unsub) unsub();
291
- reject(new Error('3D assets did not become idle within timeout'));
292
- }
422
+ stable = _context3.sent;
423
+ log('waitForIdle stable check', stable);
424
+ if (stable) finishOk();
293
425
  case 4:
294
426
  case "end":
295
427
  return _context3.stop();
@@ -315,7 +447,9 @@ function installGltfTracker() {
315
447
  var uninstall = function uninstall() {
316
448
  var _XHR$prototype3, _XHR$prototype4;
317
449
  g.refCount -= 1;
450
+ log('uninstall tracker refCount--', g.refCount);
318
451
  if (g.refCount > 0) return;
452
+ log('uninstall tracker (final) restoring hooks');
319
453
  var XHR = window.XMLHttpRequest;
320
454
  if (XHR !== null && XHR !== void 0 && (_XHR$prototype3 = XHR.prototype) !== null && _XHR$prototype3 !== void 0 && _XHR$prototype3.open && g.originalOpen) XHR.prototype.open = g.originalOpen;
321
455
  if (XHR !== null && XHR !== void 0 && (_XHR$prototype4 = XHR.prototype) !== null && _XHR$prototype4 !== void 0 && _XHR$prototype4.send && g.originalSend) XHR.prototype.send = g.originalSend;
@@ -328,6 +462,7 @@ function installGltfTracker() {
328
462
  g.originalSend = null;
329
463
  };
330
464
  g.refCount += 1;
465
+ log('install tracker refCount++', g.refCount);
331
466
  installIfNeeded();
332
467
  return {
333
468
  getInFlight: function getInFlight() {
@@ -342,92 +477,198 @@ export function renderKitchenSimulator(container) {
342
477
  var _props$framesPerEvent, _props$waitForGltfIdl, _props$gltfTimeoutMs;
343
478
  var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
344
479
  if (!container) throw new Error('renderKitchenSimulator: container is required');
480
+ var DEBUG_KEY = '__kitchenSimulatorDebug__';
481
+ var debugEnabled = !!props.debug || typeof window !== 'undefined' && !!window[DEBUG_KEY];
482
+ var _makeLogger2 = makeLogger(function () {
483
+ return debugEnabled;
484
+ }),
485
+ log = _makeLogger2.log,
486
+ warn = _makeLogger2.warn,
487
+ error = _makeLogger2.error;
488
+
489
+ // ---- Long-task observer (find main-thread blocks) ----
490
+ var longTaskObserver = null;
491
+ if (typeof window !== 'undefined' && 'PerformanceObserver' in window) {
492
+ try {
493
+ longTaskObserver = new PerformanceObserver(function (list) {
494
+ var _iterator2 = _createForOfIteratorHelper(list.getEntries()),
495
+ _step2;
496
+ try {
497
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
498
+ var entry = _step2.value;
499
+ // entry.duration is the smoking gun when UI freezes
500
+ warn('Long task detected', {
501
+ name: entry.name,
502
+ duration: entry.duration,
503
+ startTime: entry.startTime
504
+ });
505
+ }
506
+ } catch (err) {
507
+ _iterator2.e(err);
508
+ } finally {
509
+ _iterator2.f();
510
+ }
511
+ });
512
+ // may throw in some browsers
513
+ longTaskObserver.observe({
514
+ entryTypes: ['longtask']
515
+ });
516
+ log('Long-task observer installed');
517
+ } catch (_unused3) {
518
+ // ignore
519
+ }
520
+ }
345
521
 
346
522
  // ✅ Reuse existing API
347
523
  if (container[API_KEY]) {
348
524
  var _container$API_KEY$__, _container$API_KEY;
525
+ log('Reusing existing API; calling __render with new props');
349
526
  (_container$API_KEY$__ = (_container$API_KEY = container[API_KEY]).__render) === null || _container$API_KEY$__ === void 0 || _container$API_KEY$__.call(_container$API_KEY, props);
350
527
  return container[API_KEY];
351
528
  }
352
529
 
353
- // ✅ Reuse root
530
+ // ✅ Root
354
531
  var root = container[ROOT_KEY];
355
532
  if (!root) {
356
533
  root = createRoot(container);
357
534
  container[ROOT_KEY] = root;
535
+ log('Created new React root');
358
536
  }
359
537
  var setExternalEventFn = null;
360
538
  var destroyed = false;
361
539
  var queue = [];
362
540
  var pendingMarkers = new Set();
363
541
  var MARKER = Symbol('marker');
364
- var gltfTracker = installGltfTracker();
365
-
366
- // FAST defaults (safe)
542
+ var gltfTracker = installGltfTracker(debugEnabled);
367
543
  var defaultFramesPerEvent = (_props$framesPerEvent = props.framesPerEvent) !== null && _props$framesPerEvent !== void 0 ? _props$framesPerEvent : 1;
368
544
  var waitForAssets = (_props$waitForGltfIdl = props.waitForGltfIdleAfterEachEvent) !== null && _props$waitForGltfIdl !== void 0 ? _props$waitForGltfIdl : true;
369
545
  var defaultTimeout = (_props$gltfTimeoutMs = props.gltfTimeoutMs) !== null && _props$gltfTimeoutMs !== void 0 ? _props$gltfTimeoutMs : 30000;
546
+ var draining = false;
370
547
 
371
- // If you want ultra-fast UI responsiveness, you can disable waiting per-event
372
- // and only wait on “important” events, see comment in settle() below.
548
+ // ---- Ready gate (super important for first event) ----
549
+ var readyResolve = null;
550
+ var readyReject = null;
551
+ var readyPromise = new Promise(function (res, rej) {
552
+ readyResolve = res;
553
+ readyReject = rej;
554
+ });
373
555
 
374
- var draining = false;
556
+ // ---- RAF diagnostic wrapper ----
557
+ function nextFrameDiag() {
558
+ var label = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'raf';
559
+ var warnAfterMs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 250;
560
+ if (typeof window === 'undefined') return Promise.resolve();
561
+ return new Promise(function (resolve) {
562
+ var done = false;
563
+ var start = performance.now();
564
+ var t = setTimeout(function () {
565
+ var _document, _document2;
566
+ if (done) return;
567
+
568
+ // If this fires, RAF is not arriving (hidden tab / throttling) or main thread blocked
569
+ warn('RAF not fired within threshold', {
570
+ label: label,
571
+ warnAfterMs: warnAfterMs,
572
+ elapsedMs: performance.now() - start,
573
+ visibilityState: (_document = document) === null || _document === void 0 ? void 0 : _document.visibilityState,
574
+ hidden: (_document2 = document) === null || _document2 === void 0 ? void 0 : _document2.hidden,
575
+ gltfInFlight: gltfTracker.getInFlight(),
576
+ queueLength: queue.length,
577
+ draining: draining,
578
+ destroyed: destroyed
579
+ });
580
+
581
+ // Optional fail-open so you don't hang forever:
582
+ // If you want STRICT behavior, comment the next 2 lines and only keep logging.
583
+ done = true;
584
+ resolve();
585
+ }, warnAfterMs);
586
+ requestAnimationFrame(function () {
587
+ if (done) return;
588
+ done = true;
589
+ clearTimeout(t);
590
+ resolve();
591
+ });
592
+ });
593
+ }
375
594
  function isSyncScene(ev) {
376
595
  var _ev$payload;
377
596
  return (ev === null || ev === void 0 ? void 0 : ev.type) === 'EXTERNAL_EVENT_SYNC_SCENE' || (ev === null || ev === void 0 || (_ev$payload = ev.payload) === null || _ev$payload === void 0 ? void 0 : _ev$payload.mode) === 'sync-scene' || (ev === null || ev === void 0 ? void 0 : ev.__sync) === true;
378
597
  }
379
- function settle(_x2) {
598
+ function settle(_x2, _x3) {
380
599
  return _settle.apply(this, arguments);
381
600
  }
382
601
  function _settle() {
383
- _settle = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee7(ev) {
384
- var _ev$framesPerEvent, _ev$waitForGltfIdleAf;
385
- var frames, i, shouldWait, _ev$gltfTimeoutMs, timeoutMs;
386
- return _regeneratorRuntime.wrap(function (_context7) {
387
- while (1) switch (_context7.prev = _context7.next) {
602
+ _settle = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee8(ev, meta) {
603
+ var _ev$framesPerEvent, _ev$waitForGltfIdleAf, _ev$gltfTimeoutMs, _document7, _document8;
604
+ var frames, shouldWait, timeoutMs, i, start;
605
+ return _regeneratorRuntime.wrap(function (_context8) {
606
+ while (1) switch (_context8.prev = _context8.next) {
388
607
  case 0:
389
- frames = (_ev$framesPerEvent = ev === null || ev === void 0 ? void 0 : ev.framesPerEvent) !== null && _ev$framesPerEvent !== void 0 ? _ev$framesPerEvent : defaultFramesPerEvent; // (1) allow react/reducers to run (fixes “must zoom to see updates”)
608
+ frames = (_ev$framesPerEvent = ev === null || ev === void 0 ? void 0 : ev.framesPerEvent) !== null && _ev$framesPerEvent !== void 0 ? _ev$framesPerEvent : defaultFramesPerEvent;
609
+ shouldWait = (_ev$waitForGltfIdleAf = ev === null || ev === void 0 ? void 0 : ev.waitForGltfIdleAfterEachEvent) !== null && _ev$waitForGltfIdleAf !== void 0 ? _ev$waitForGltfIdleAf : waitForAssets;
610
+ timeoutMs = (_ev$gltfTimeoutMs = ev === null || ev === void 0 ? void 0 : ev.gltfTimeoutMs) !== null && _ev$gltfTimeoutMs !== void 0 ? _ev$gltfTimeoutMs : defaultTimeout;
611
+ log('settle:start', _objectSpread(_objectSpread({}, meta), {}, {
612
+ frames: frames,
613
+ shouldWait: shouldWait,
614
+ timeoutMs: timeoutMs,
615
+ visibilityState: (_document7 = document) === null || _document7 === void 0 ? void 0 : _document7.visibilityState,
616
+ hidden: (_document8 = document) === null || _document8 === void 0 ? void 0 : _document8.hidden
617
+ }));
618
+
619
+ // (1) RAF frames (diagnostic)
390
620
  i = 0;
391
621
  case 1:
392
622
  if (!(i < frames)) {
393
- _context7.next = 3;
623
+ _context8.next = 4;
394
624
  break;
395
625
  }
396
- _context7.next = 2;
397
- return nextFrame();
626
+ _context8.next = 2;
627
+ return nextFrameDiag("settle:frame ".concat(i + 1, "/").concat(frames), 500);
398
628
  case 2:
629
+ if (debugEnabled) log('settle:after frame', _objectSpread(_objectSpread({}, meta), {}, {
630
+ i: i + 1
631
+ }));
632
+ case 3:
399
633
  i += 1;
400
- _context7.next = 1;
634
+ _context8.next = 1;
401
635
  break;
402
- case 3:
403
- // (2) optionally wait for assets
404
- // fastest safe approach: keep ON for events that add/replace/load models
405
- // You can override per-event via ev.waitForGltfIdleAfterEachEvent = false
406
- shouldWait = (_ev$waitForGltfIdleAf = ev === null || ev === void 0 ? void 0 : ev.waitForGltfIdleAfterEachEvent) !== null && _ev$waitForGltfIdleAf !== void 0 ? _ev$waitForGltfIdleAf : waitForAssets;
636
+ case 4:
407
637
  if (!shouldWait) {
408
- _context7.next = 4;
638
+ _context8.next = 6;
409
639
  break;
410
640
  }
411
- timeoutMs = (_ev$gltfTimeoutMs = ev === null || ev === void 0 ? void 0 : ev.gltfTimeoutMs) !== null && _ev$gltfTimeoutMs !== void 0 ? _ev$gltfTimeoutMs : defaultTimeout;
412
- _context7.next = 4;
641
+ start = Date.now();
642
+ log('settle:waitForIdle start', _objectSpread(_objectSpread({}, meta), {}, {
643
+ timeoutMs: timeoutMs,
644
+ gltfInFlight: gltfTracker.getInFlight()
645
+ }));
646
+ _context8.next = 5;
413
647
  return gltfTracker.waitForIdle({
414
648
  timeoutMs: timeoutMs
415
649
  });
416
- case 4:
417
- _context7.next = 5;
418
- return nextFrame();
419
650
  case 5:
651
+ log('settle:waitForIdle done', _objectSpread(_objectSpread({}, meta), {}, {
652
+ waitedMs: Date.now() - start,
653
+ gltfInFlight: gltfTracker.getInFlight()
654
+ }));
655
+ case 6:
656
+ _context8.next = 7;
657
+ return nextFrameDiag('settle:final commit frame', 500);
658
+ case 7:
420
659
  if (!isSyncScene(ev)) {
421
- _context7.next = 6;
660
+ _context8.next = 8;
422
661
  break;
423
662
  }
424
- _context7.next = 6;
425
- return nextFrame();
426
- case 6:
663
+ _context8.next = 8;
664
+ return nextFrameDiag('settle:sync-scene extra frame', 500);
665
+ case 8:
666
+ log('settle:done', meta);
667
+ case 9:
427
668
  case "end":
428
- return _context7.stop();
669
+ return _context8.stop();
429
670
  }
430
- }, _callee7);
671
+ }, _callee8);
431
672
  }));
432
673
  return _settle.apply(this, arguments);
433
674
  }
@@ -435,64 +676,108 @@ export function renderKitchenSimulator(container) {
435
676
  return _drain.apply(this, arguments);
436
677
  }
437
678
  function _drain() {
438
- _drain = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee8() {
439
- var item, _t;
440
- return _regeneratorRuntime.wrap(function (_context8) {
441
- while (1) switch (_context8.prev = _context8.next) {
679
+ _drain = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee9() {
680
+ var watchdog, item, meta, _err$message2, _t2;
681
+ return _regeneratorRuntime.wrap(function (_context9) {
682
+ while (1) switch (_context9.prev = _context9.next) {
442
683
  case 0:
443
684
  if (!(draining || destroyed)) {
444
- _context8.next = 1;
685
+ _context9.next = 1;
445
686
  break;
446
687
  }
447
- return _context8.abrupt("return");
688
+ if (debugEnabled) log('drain:skip', {
689
+ draining: draining,
690
+ destroyed: destroyed,
691
+ queueLength: queue.length
692
+ });
693
+ return _context9.abrupt("return");
448
694
  case 1:
449
695
  draining = true;
450
- _context8.prev = 2;
696
+
697
+ // Watchdog: if we’re “stuck” in draining, dump state periodically
698
+ watchdog = setInterval(function () {
699
+ var _document9, _document0;
700
+ warn('drain watchdog', {
701
+ destroyed: destroyed,
702
+ draining: draining,
703
+ queueLength: queue.length,
704
+ pendingMarkers: pendingMarkers.size,
705
+ gltfInFlight: gltfTracker.getInFlight(),
706
+ visibilityState: (_document9 = document) === null || _document9 === void 0 ? void 0 : _document9.visibilityState,
707
+ hidden: (_document0 = document) === null || _document0 === void 0 ? void 0 : _document0.hidden
708
+ });
709
+ }, 4000);
710
+ _context9.prev = 2;
711
+ _context9.next = 3;
712
+ return readyPromise;
451
713
  case 3:
452
714
  if (!(!destroyed && queue.length)) {
453
- _context8.next = 11;
715
+ _context9.next = 11;
454
716
  break;
455
717
  }
456
718
  if (setExternalEventFn) {
457
- _context8.next = 5;
719
+ _context9.next = 5;
458
720
  break;
459
721
  }
460
- _context8.next = 4;
461
- return nextFrame();
722
+ warn('drain: no setExternalEventFn even after ready (unexpected)');
723
+ _context9.next = 4;
724
+ return nextFrameDiag('drain:waiting for setExternalEventFn', 500);
462
725
  case 4:
463
- return _context8.abrupt("continue", 3);
726
+ return _context9.abrupt("continue", 3);
464
727
  case 5:
465
728
  item = queue.shift();
466
729
  if (!(item && item.__marker === MARKER)) {
467
- _context8.next = 6;
730
+ _context9.next = 6;
468
731
  break;
469
732
  }
470
733
  pendingMarkers["delete"](item.token);
471
- return _context8.abrupt("continue", 3);
734
+ log('drain:marker consumed', {
735
+ pendingMarkers: pendingMarkers.size,
736
+ queueLength: queue.length
737
+ });
738
+ return _context9.abrupt("continue", 3);
472
739
  case 6:
740
+ meta = {
741
+ eventType: item === null || item === void 0 ? void 0 : item.type,
742
+ queueLengthAfterShift: queue.length,
743
+ pendingMarkers: pendingMarkers.size,
744
+ gltfInFlight: gltfTracker.getInFlight()
745
+ };
746
+ log('drain:event begin', meta);
747
+ _context9.prev = 7;
473
748
  setExternalEventFn(item);
474
- _context8.prev = 7;
475
- _context8.next = 8;
476
- return settle(item);
749
+ log('drain:setExternalEventFn called', meta);
750
+ _context9.next = 8;
751
+ return settle(item, meta);
477
752
  case 8:
478
- _context8.next = 10;
753
+ log('drain:event done', meta);
754
+ _context9.next = 10;
479
755
  break;
480
756
  case 9:
481
- _context8.prev = 9;
482
- _t = _context8["catch"](7);
483
- console.error('settle failed', _t);
757
+ _context9.prev = 9;
758
+ _t2 = _context9["catch"](7);
759
+ error('drain:event failed', _objectSpread(_objectSpread({}, meta), {}, {
760
+ err: (_err$message2 = _t2 === null || _t2 === void 0 ? void 0 : _t2.message) !== null && _err$message2 !== void 0 ? _err$message2 : _t2
761
+ }));
484
762
  case 10:
485
- _context8.next = 3;
763
+ _context9.next = 3;
486
764
  break;
487
765
  case 11:
488
- _context8.prev = 11;
766
+ _context9.prev = 11;
767
+ clearInterval(watchdog);
489
768
  draining = false;
490
- return _context8.finish(11);
769
+ log('drain:done', {
770
+ destroyed: destroyed,
771
+ queueLength: queue.length,
772
+ pendingMarkers: pendingMarkers.size,
773
+ gltfInFlight: gltfTracker.getInFlight()
774
+ });
775
+ return _context9.finish(11);
491
776
  case 12:
492
777
  case "end":
493
- return _context8.stop();
778
+ return _context9.stop();
494
779
  }
495
- }, _callee8, null, [[2,, 11, 12], [7, 9]]);
780
+ }, _callee9, null, [[2,, 11, 12], [7, 9]]);
496
781
  }));
497
782
  return _drain.apply(this, arguments);
498
783
  }
@@ -513,22 +798,42 @@ export function renderKitchenSimulator(container) {
513
798
  value: function componentDidMount() {
514
799
  var _this3 = this;
515
800
  this._mounted = true;
801
+ log('Wrapper mounted -> ready');
516
802
  setExternalEventFn = function setExternalEventFn(newEvent) {
517
803
  if (!_this3._mounted) return;
804
+ log('Wrapper setState(externalEvent)', {
805
+ type: newEvent === null || newEvent === void 0 ? void 0 : newEvent.type
806
+ });
518
807
  _this3.setState({
519
808
  externalEvent: newEvent
520
809
  });
521
810
  };
811
+
812
+ // ✅ resolve readiness here (first time)
813
+ if (readyResolve) {
814
+ readyResolve(true);
815
+ readyResolve = null;
816
+ }
522
817
  }
523
818
  }, {
524
819
  key: "componentWillUnmount",
525
820
  value: function componentWillUnmount() {
821
+ log('Wrapper will unmount');
526
822
  this._mounted = false;
527
823
  setExternalEventFn = null;
824
+
825
+ // If unmount happens before ready, reject so drain can stop cleanly
826
+ if (readyReject) {
827
+ readyReject(new Error('Wrapper unmounted before ready'));
828
+ readyReject = null;
829
+ }
528
830
  }
529
831
  }, {
530
832
  key: "render",
531
833
  value: function render() {
834
+ if (debugEnabled) log('Wrapper render', {
835
+ hasExternalEvent: !!this.state.externalEvent
836
+ });
532
837
  return /*#__PURE__*/React.createElement(LiteRenderer, _extends({}, this.props, {
533
838
  externalEvent: this.state.externalEvent
534
839
  }));
@@ -537,29 +842,46 @@ export function renderKitchenSimulator(container) {
537
842
  }(React.Component);
538
843
  var api = {
539
844
  __render: function __render(nextProps) {
845
+ log('__render called', {
846
+ debug: !!(nextProps !== null && nextProps !== void 0 && nextProps.debug)
847
+ });
540
848
  root.render(/*#__PURE__*/React.createElement(Wrapper, nextProps));
541
849
  },
542
- // host can query current inFlight
850
+ whenReady: function whenReady() {
851
+ return readyPromise;
852
+ },
543
853
  getGltfInFlight: function getGltfInFlight() {
544
854
  return gltfTracker.getInFlight();
545
855
  },
546
- // ✅ host can subscribe to inFlight changes (loader)
547
856
  subscribeGltfInFlight: function subscribeGltfInFlight(cb) {
548
857
  return gltfTracker.subscribe(cb);
549
858
  },
550
859
  sendExternalEvents: function sendExternalEvents(eventOrEvents) {
860
+ var _document3, _document4;
861
+ var _ref5 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
862
+ _ref5$timeoutMs = _ref5.timeoutMs,
863
+ timeoutMs = _ref5$timeoutMs === void 0 ? 60000 : _ref5$timeoutMs;
551
864
  var events = Array.isArray(eventOrEvents) ? eventOrEvents : [eventOrEvents];
552
- var _iterator2 = _createForOfIteratorHelper(events),
553
- _step2;
865
+ var batchId = Math.random().toString(16).slice(2);
866
+ log('sendExternalEvents:enqueue', {
867
+ batchId: batchId,
868
+ count: events.length,
869
+ timeoutMs: timeoutMs,
870
+ visibilityState: (_document3 = document) === null || _document3 === void 0 ? void 0 : _document3.visibilityState,
871
+ hidden: (_document4 = document) === null || _document4 === void 0 ? void 0 : _document4.hidden,
872
+ gltfInFlight: gltfTracker.getInFlight()
873
+ });
874
+ var _iterator3 = _createForOfIteratorHelper(events),
875
+ _step3;
554
876
  try {
555
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
556
- var e = _step2.value;
877
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
878
+ var e = _step3.value;
557
879
  queue.push(e);
558
880
  }
559
881
  } catch (err) {
560
- _iterator2.e(err);
882
+ _iterator3.e(err);
561
883
  } finally {
562
- _iterator2.f();
884
+ _iterator3.f();
563
885
  }
564
886
  var token = Symbol('batch');
565
887
  pendingMarkers.add(token);
@@ -567,40 +889,68 @@ export function renderKitchenSimulator(container) {
567
889
  __marker: MARKER,
568
890
  token: token
569
891
  });
892
+ log('sendExternalEvents:marker added', {
893
+ batchId: batchId,
894
+ queueLength: queue.length,
895
+ pendingMarkers: pendingMarkers.size
896
+ });
570
897
  drain();
571
-
572
- // resolve when marker cleared
573
898
  return new Promise(function (resolve) {
899
+ var start = Date.now();
574
900
  var check = /*#__PURE__*/function () {
575
- var _ref5 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee6() {
576
- return _regeneratorRuntime.wrap(function (_context6) {
577
- while (1) switch (_context6.prev = _context6.next) {
901
+ var _ref6 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee7() {
902
+ var _document5, _document6;
903
+ return _regeneratorRuntime.wrap(function (_context7) {
904
+ while (1) switch (_context7.prev = _context7.next) {
578
905
  case 0:
579
906
  if (destroyed) {
580
- _context6.next = 3;
907
+ _context7.next = 4;
581
908
  break;
582
909
  }
583
- if (!pendingMarkers.has(token)) {
584
- _context6.next = 2;
910
+ if (pendingMarkers.has(token)) {
911
+ _context7.next = 1;
585
912
  break;
586
913
  }
587
- _context6.next = 1;
588
- return nextFrame();
914
+ log('sendExternalEvents:resolved', {
915
+ batchId: batchId,
916
+ ms: Date.now() - start
917
+ });
918
+ resolve(true);
919
+ return _context7.abrupt("return");
589
920
  case 1:
590
- return _context6.abrupt("continue", 0);
921
+ if (!(Date.now() - start > timeoutMs)) {
922
+ _context7.next = 2;
923
+ break;
924
+ }
925
+ error('sendExternalEvents timed out', {
926
+ batchId: batchId,
927
+ timeoutMs: timeoutMs,
928
+ ms: Date.now() - start,
929
+ queueLength: queue.length,
930
+ pendingMarkers: pendingMarkers.size,
931
+ gltfInFlight: gltfTracker.getInFlight(),
932
+ visibilityState: (_document5 = document) === null || _document5 === void 0 ? void 0 : _document5.visibilityState,
933
+ hidden: (_document6 = document) === null || _document6 === void 0 ? void 0 : _document6.hidden
934
+ });
935
+ pendingMarkers["delete"](token); // fail-open
936
+ resolve(false);
937
+ return _context7.abrupt("return");
591
938
  case 2:
592
- resolve(true);
593
- return _context6.abrupt("return");
939
+ _context7.next = 3;
940
+ return nextFrameDiag("sendExternalEvents:waiting batch=".concat(batchId), 1000);
594
941
  case 3:
595
- resolve(false);
942
+ _context7.next = 0;
943
+ break;
596
944
  case 4:
945
+ resolve(false);
946
+ case 5:
597
947
  case "end":
598
- return _context6.stop();
948
+ return _context7.stop();
599
949
  }
600
- }, _callee6);
950
+ }, _callee7);
601
951
  }));
602
952
  return function check() {
603
- return _ref5.apply(this, arguments);
953
+ return _ref6.apply(this, arguments);
604
954
  };
605
955
  }();
606
956
  check();
@@ -617,6 +967,11 @@ export function renderKitchenSimulator(container) {
617
967
  destroyed = true;
618
968
  api.clearQueue();
619
969
  gltfTracker.uninstall();
970
+ try {
971
+ if (longTaskObserver) longTaskObserver.disconnect();
972
+ } catch (_unused4) {
973
+ // ignore
974
+ }
620
975
  var doUnmount = function doUnmount() {
621
976
  try {
622
977
  root.unmount();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kitchen-simulator",
3
- "version": "5.10.8-react.18",
3
+ "version": "5.10.10-react.18",
4
4
  "description": "It is a kitchen simulator (self-contained micro-frontend).",
5
5
  "license": "MIT",
6
6
  "module": "es/index.js",