kitchen-simulator 6.0.3-react.18 → 7.0.1-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.
@@ -75,7 +75,6 @@ var LiteKitchenConfigurator = /*#__PURE__*/function (_Component) {
75
75
  isSaved: false,
76
76
  isLeaving: false
77
77
  };
78
- _this._catalogInitRequested = false;
79
78
  _this.openFloor = _this.openFloor.bind(_this);
80
79
  _this.openCabinet = _this.openCabinet.bind(_this);
81
80
  _this.openFinishing = _this.openFinishing.bind(_this);
@@ -299,10 +298,7 @@ var LiteKitchenConfigurator = /*#__PURE__*/function (_Component) {
299
298
  extractedState = _this$props.extractedState,
300
299
  projectActions = _this$props.projectActions;
301
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']);
302
- if (!catalogReady && !this._catalogInitRequested) {
303
- this._catalogInitRequested = true;
304
- projectActions.initCatalog(catalog);
305
- }
301
+ if (!catalogReady) projectActions.initCatalog(catalog);
306
302
  }
307
303
  }, {
308
304
  key: "componentDidUpdate",
@@ -314,17 +310,12 @@ var LiteKitchenConfigurator = /*#__PURE__*/function (_Component) {
314
310
  projectActions = _this$props2.projectActions,
315
311
  catalog = _this$props2.catalog;
316
312
 
317
- // handle external event when it changes
318
- if (prevProps.externalEvent !== externalEvent && externalEvent) {
313
+ // same behavior: handle external event when it changes
314
+ if (prevProps.externalEvent !== externalEvent) {
319
315
  handleExternalEvent(this.props);
320
316
  }
321
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']);
322
- if (catalogReady) {
323
- this._catalogInitRequested = false; // allow re-init if state resets later
324
- } else if (!this._catalogInitRequested) {
325
- this._catalogInitRequested = true;
326
- projectActions.initCatalog(catalog);
327
- }
318
+ if (!catalogReady) projectActions.initCatalog(catalog);
328
319
  }
329
320
  }, {
330
321
  key: "isProjectEmpty",
@@ -347,20 +338,20 @@ var LiteKitchenConfigurator = /*#__PURE__*/function (_Component) {
347
338
  }
348
339
  var _viewer2D = extractedState.getIn(['viewer2D']);
349
340
  if (!_viewer2D || _viewer2D.size <= 0) return extractedState;
350
- var e = _viewer2D.get('e');
351
- var f = _viewer2D.get('f');
352
- if (e !== 0 || f !== 0) return extractedState;
353
- var viewerWidth = _viewer2D.get('viewerWidth');
354
- var viewerHeight = _viewer2D.get('viewerHeight');
355
- var SVGWidth = _viewer2D.get('SVGWidth');
356
- var SVGHeight = _viewer2D.get('SVGHeight');
357
- var cacheKey = "".concat(width, ":").concat(height, ":").concat(viewerWidth, ":").concat(viewerHeight, ":").concat(SVGWidth, ":").concat(SVGHeight);
341
+ var v = _viewer2D.toJS();
342
+
343
+ // Only do the "center viewer2D if e/f are zero" logic.
344
+ // No need to build keys from unrelated parts of state.
345
+ if (v.e !== 0 || v.f !== 0) return extractedState;
346
+
347
+ // Build a cache key ONLY for this viewer2D-centering computation.
348
+ var cacheKey = "".concat(width, ":").concat(height, ":").concat(v.viewerWidth, ":").concat(v.viewerHeight, ":").concat(v.SVGWidth, ":").concat(v.SVGHeight);
358
349
  if (this._cachedViewer2DKey === cacheKey && this._cachedExtractedState) {
359
350
  return this._cachedExtractedState;
360
351
  }
361
352
  var centeredViewer2D = _viewer2D.merge({
362
- e: viewerWidth / 2 - SVGWidth / 2,
363
- f: viewerHeight / 2 - SVGHeight / 2,
353
+ e: v.viewerWidth / 2 - v.SVGWidth / 2,
354
+ f: v.viewerHeight / 2 - v.SVGHeight / 2,
364
355
  a: 0.99,
365
356
  d: 0.99
366
357
  });
package/es/WorkSpace.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
2
  import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
3
3
  import _regeneratorRuntime from "@babel/runtime/regenerator";
4
- import React, { useState } from 'react';
4
+ import React, { useEffect, useState } from 'react';
5
5
  import { Map } from 'immutable';
6
6
  import { useResizeDetector } from 'react-resize-detector';
7
7
  import projectItemsCatalog from "./mocks/projectItemsCatalog.json";
@@ -62,6 +62,13 @@ function WorkSpace(props) {
62
62
  _useState2 = _slicedToArray(_useState, 2),
63
63
  externalEvent = _useState2[0],
64
64
  setExternalEvent = _useState2[1];
65
+ useEffect(function () {
66
+ setExternalEvent({
67
+ type: EXTERNAL_EVENT_LOAD_PROJECT,
68
+ // send request for sync scene data to 3DTool
69
+ payload: JSON.parse(mockProps.projectElement[0].project_data)
70
+ });
71
+ }, []);
65
72
  var offset = 5;
66
73
  return /*#__PURE__*/React.createElement("div", {
67
74
  className: "flex gap-4"
package/es/index.js CHANGED
@@ -5,71 +5,25 @@ import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConst
5
5
  import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
6
6
  import _inherits from "@babel/runtime/helpers/esm/inherits";
7
7
  import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
8
- import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
9
8
  function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
10
9
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
11
10
  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; } } }; }
12
11
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
13
12
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
14
13
  import _regeneratorRuntime from "@babel/runtime/regenerator";
15
- // kitchen-simulator/index.js (or wherever renderKitchenSimulator lives)
16
14
  import React from 'react';
17
- import { createRoot } from 'react-dom/client';
18
- import LiteRenderer from "./LiteRenderer";
19
15
  import * as Three from 'three';
16
+ import LiteRenderer from "./LiteRenderer";
17
+ import { createRoot } from 'react-dom/client';
20
18
  var ROOT_KEY = '__kitchenSimulatorRoot__';
21
19
  var API_KEY = '__kitchenSimulatorApi__';
22
- function makeLogger(getEnabled) {
23
- var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '[kitchen-simulator]';
24
- var now = function now() {
25
- return (typeof performance !== 'undefined' && performance.now ? performance.now() : Date.now()).toFixed(1);
26
- };
27
- var safe = function safe(v) {
28
- try {
29
- if (v == null) return v;
30
- if (typeof v === 'string') return v;
31
- if (typeof v === 'number' || typeof v === 'boolean') return v;
32
- return JSON.stringify(v, function (k, val) {
33
- if (k === 'children' || k === 'parent') return '[omitted]';
34
- if (typeof val === 'function') return '[fn]';
35
- return val;
36
- });
37
- } catch (_unused) {
38
- return '[unserializable]';
39
- }
40
- };
41
- var log = function log() {
42
- var _console;
43
- if (!getEnabled()) return;
44
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
45
- args[_key] = arguments[_key];
46
- }
47
- (_console = console).log.apply(_console, ["".concat(prefix, " ").concat(now(), "ms")].concat(_toConsumableArray(args.map(safe))));
48
- };
49
- var warn = function warn() {
50
- var _console2;
51
- if (!getEnabled()) return;
52
- for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
53
- args[_key2] = arguments[_key2];
54
- }
55
- (_console2 = console).warn.apply(_console2, ["".concat(prefix, " ").concat(now(), "ms")].concat(_toConsumableArray(args.map(safe))));
56
- };
57
- var error = function error() {
58
- var _console3;
59
- if (!getEnabled()) return;
60
- for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
61
- args[_key3] = arguments[_key3];
62
- }
63
- (_console3 = console).error.apply(_console3, ["".concat(prefix, " ").concat(now(), "ms")].concat(_toConsumableArray(args.map(safe))));
64
- };
65
- return {
66
- log: log,
67
- warn: warn,
68
- error: error
69
- };
20
+ function nextFrame() {
21
+ return new Promise(function (resolve) {
22
+ return requestAnimationFrame(resolve);
23
+ });
70
24
  }
71
25
 
72
- // ---- Your URL rewrite + TextureLoader patch stays as you had it ----
26
+ // DIY-714 [Temp Fix] Rewrite API URLs
73
27
  var API_HOST_REGEX = /(https?:\/\/)?(api\.diydesignspace\.com|api\.addovisuals\.com|127\.0\.0\.1:4002)/;
74
28
  var API_HOST_REPLACEMENT = 'https://api-old.diydesignspace.com';
75
29
  function rewriteApiUrl(url) {
@@ -134,7 +88,7 @@ function installGltfTracker() {
134
88
  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 : '';
135
89
  var u = s.toLowerCase().split('?')[0]; // ignore cache params
136
90
  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');
137
- } catch (_unused2) {
91
+ } catch (_unused) {
138
92
  return false;
139
93
  }
140
94
  };
@@ -171,8 +125,8 @@ function installGltfTracker() {
171
125
  XHR.prototype.open = function (method, url) {
172
126
  var _g$originalOpen;
173
127
  this.__is3dAssetRequest = is3dAssetUrl(url);
174
- for (var _len4 = arguments.length, rest = new Array(_len4 > 2 ? _len4 - 2 : 0), _key4 = 2; _key4 < _len4; _key4++) {
175
- rest[_key4 - 2] = arguments[_key4];
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];
176
130
  }
177
131
  return (_g$originalOpen = g.originalOpen).call.apply(_g$originalOpen, [this, method, url].concat(rest));
178
132
  };
@@ -195,8 +149,8 @@ function installGltfTracker() {
195
149
  this.addEventListener('abort', _done);
196
150
  this.addEventListener('timeout', _done);
197
151
  }
198
- for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
199
- args[_key5] = arguments[_key5];
152
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
153
+ args[_key2] = arguments[_key2];
200
154
  }
201
155
  return g.originalSend.apply(this, args);
202
156
  };
@@ -206,9 +160,9 @@ function installGltfTracker() {
206
160
  g.originalFetch = window.fetch;
207
161
  if (typeof g.originalFetch === 'function') {
208
162
  window.fetch = /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
209
- var _len6,
163
+ var _len3,
210
164
  args,
211
- _key6,
165
+ _key3,
212
166
  input,
213
167
  init,
214
168
  newUrl,
@@ -217,8 +171,8 @@ function installGltfTracker() {
217
171
  return _regeneratorRuntime.wrap(function (_context2) {
218
172
  while (1) switch (_context2.prev = _context2.next) {
219
173
  case 0:
220
- for (_len6 = _args2.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
221
- args[_key6] = _args2[_key6];
174
+ for (_len3 = _args2.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
175
+ args[_key3] = _args2[_key3];
222
176
  }
223
177
  input = args[0], init = args[1]; // DIY-714 [Temp Fix] Rewrite API URLs
224
178
  if (typeof input === 'string') {
@@ -404,104 +358,96 @@ export function renderKitchenSimulator(container) {
404
358
  var _props$framesPerEvent, _props$waitForGltfIdl, _props$gltfTimeoutMs;
405
359
  var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
406
360
  if (!container) throw new Error('renderKitchenSimulator: container is required');
407
- var DEBUG_KEY = '__kitchenSimulatorDebug__';
408
- var debugEnabled = !!props.debug || typeof window !== 'undefined' && !!window[DEBUG_KEY];
409
- var _makeLogger = makeLogger(function () {
410
- return debugEnabled;
411
- }),
412
- log = _makeLogger.log,
413
- warn = _makeLogger.warn,
414
- error = _makeLogger.error;
415
361
 
416
362
  // ✅ Reuse existing API
417
363
  if (container[API_KEY]) {
418
364
  var _container$API_KEY$__, _container$API_KEY;
419
- log('Reusing existing API; calling __render with new props');
420
365
  (_container$API_KEY$__ = (_container$API_KEY = container[API_KEY]).__render) === null || _container$API_KEY$__ === void 0 || _container$API_KEY$__.call(_container$API_KEY, props);
421
366
  return container[API_KEY];
422
367
  }
423
368
 
424
- // ✅ Root
369
+ // ✅ Reuse root
425
370
  var root = container[ROOT_KEY];
426
371
  if (!root) {
427
372
  root = createRoot(container);
428
373
  container[ROOT_KEY] = root;
429
- log('Created new React root');
430
374
  }
431
375
  var setExternalEventFn = null;
432
376
  var destroyed = false;
377
+ var resolveReady = null;
378
+ var readyPromise = new Promise(function (res) {
379
+ return resolveReady = res;
380
+ });
433
381
  var queue = [];
434
382
  var pendingMarkers = new Set();
435
383
  var MARKER = Symbol('marker');
384
+ var gltfTracker = installGltfTracker();
436
385
 
437
- // keep your tracker
438
- var gltfTracker = installGltfTracker(debugEnabled);
386
+ // FAST defaults (safe)
439
387
  var defaultFramesPerEvent = (_props$framesPerEvent = props.framesPerEvent) !== null && _props$framesPerEvent !== void 0 ? _props$framesPerEvent : 1;
440
388
  var waitForAssets = (_props$waitForGltfIdl = props.waitForGltfIdleAfterEachEvent) !== null && _props$waitForGltfIdl !== void 0 ? _props$waitForGltfIdl : true;
441
389
  var defaultTimeout = (_props$gltfTimeoutMs = props.gltfTimeoutMs) !== null && _props$gltfTimeoutMs !== void 0 ? _props$gltfTimeoutMs : 30000;
442
- var draining = false;
443
390
 
444
- // ---- Ready gate: mounted & setExternalEventFn installed ----
445
- var readyResolve = null;
446
- var readyReject = null;
447
- var readyPromise = new Promise(function (res, rej) {
448
- readyResolve = res;
449
- readyReject = rej;
450
- });
391
+ // If you want ultra-fast UI responsiveness, you can disable waiting per-event
392
+ // and only wait on “important” events, see comment in settle() below.
451
393
 
452
- // ---- Catalog-ready gate (NEW) ----
453
- var catalogReadyResolve = null;
454
- var catalogReadyPromise = new Promise(function (res) {
455
- catalogReadyResolve = res;
456
- });
457
- var catalogReady = false;
458
- function nextFrame() {
459
- return new Promise(function (resolve) {
460
- return requestAnimationFrame(resolve);
461
- });
394
+ var draining = false;
395
+ function isSyncScene(ev) {
396
+ var _ev$payload;
397
+ 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;
462
398
  }
463
399
  function settle(_x2) {
464
400
  return _settle.apply(this, arguments);
465
401
  }
466
402
  function _settle() {
467
- _settle = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee8(ev) {
468
- var _ev$framesPerEvent, _ev$waitForGltfIdleAf, _ev$gltfTimeoutMs;
469
- var frames, shouldWait, timeoutMs, i;
470
- return _regeneratorRuntime.wrap(function (_context8) {
471
- while (1) switch (_context8.prev = _context8.next) {
403
+ _settle = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee7(ev) {
404
+ var _ev$framesPerEvent, _ev$waitForGltfIdleAf;
405
+ var frames, i, shouldWait, _ev$gltfTimeoutMs, timeoutMs;
406
+ return _regeneratorRuntime.wrap(function (_context7) {
407
+ while (1) switch (_context7.prev = _context7.next) {
472
408
  case 0:
473
- frames = (_ev$framesPerEvent = ev === null || ev === void 0 ? void 0 : ev.framesPerEvent) !== null && _ev$framesPerEvent !== void 0 ? _ev$framesPerEvent : defaultFramesPerEvent;
474
- shouldWait = (_ev$waitForGltfIdleAf = ev === null || ev === void 0 ? void 0 : ev.waitForGltfIdleAfterEachEvent) !== null && _ev$waitForGltfIdleAf !== void 0 ? _ev$waitForGltfIdleAf : waitForAssets;
475
- timeoutMs = (_ev$gltfTimeoutMs = ev === null || ev === void 0 ? void 0 : ev.gltfTimeoutMs) !== null && _ev$gltfTimeoutMs !== void 0 ? _ev$gltfTimeoutMs : defaultTimeout; // RAF frames
409
+ 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”)
476
410
  i = 0;
477
411
  case 1:
478
412
  if (!(i < frames)) {
479
- _context8.next = 3;
413
+ _context7.next = 3;
480
414
  break;
481
415
  }
482
- _context8.next = 2;
416
+ _context7.next = 2;
483
417
  return nextFrame();
484
418
  case 2:
485
- i++;
486
- _context8.next = 1;
419
+ i += 1;
420
+ _context7.next = 1;
487
421
  break;
488
422
  case 3:
423
+ // (2) optionally wait for assets
424
+ // fastest safe approach: keep ON for events that add/replace/load models
425
+ // You can override per-event via ev.waitForGltfIdleAfterEachEvent = false
426
+ shouldWait = (_ev$waitForGltfIdleAf = ev === null || ev === void 0 ? void 0 : ev.waitForGltfIdleAfterEachEvent) !== null && _ev$waitForGltfIdleAf !== void 0 ? _ev$waitForGltfIdleAf : waitForAssets;
489
427
  if (!shouldWait) {
490
- _context8.next = 4;
428
+ _context7.next = 4;
491
429
  break;
492
430
  }
493
- _context8.next = 4;
431
+ timeoutMs = (_ev$gltfTimeoutMs = ev === null || ev === void 0 ? void 0 : ev.gltfTimeoutMs) !== null && _ev$gltfTimeoutMs !== void 0 ? _ev$gltfTimeoutMs : defaultTimeout;
432
+ _context7.next = 4;
494
433
  return gltfTracker.waitForIdle({
495
434
  timeoutMs: timeoutMs
496
435
  });
497
436
  case 4:
498
- _context8.next = 5;
437
+ _context7.next = 5;
499
438
  return nextFrame();
500
439
  case 5:
440
+ if (!isSyncScene(ev)) {
441
+ _context7.next = 6;
442
+ break;
443
+ }
444
+ _context7.next = 6;
445
+ return nextFrame();
446
+ case 6:
501
447
  case "end":
502
- return _context8.stop();
448
+ return _context7.stop();
503
449
  }
504
- }, _callee8);
450
+ }, _callee7);
505
451
  }));
506
452
  return _settle.apply(this, arguments);
507
453
  }
@@ -509,69 +455,66 @@ export function renderKitchenSimulator(container) {
509
455
  return _drain.apply(this, arguments);
510
456
  }
511
457
  function _drain() {
512
- _drain = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee9() {
513
- var item, _err$message, _t;
514
- return _regeneratorRuntime.wrap(function (_context9) {
515
- while (1) switch (_context9.prev = _context9.next) {
458
+ _drain = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee8() {
459
+ var item, _t;
460
+ return _regeneratorRuntime.wrap(function (_context8) {
461
+ while (1) switch (_context8.prev = _context8.next) {
516
462
  case 0:
517
463
  if (!(draining || destroyed)) {
518
- _context9.next = 1;
464
+ _context8.next = 1;
519
465
  break;
520
466
  }
521
- return _context9.abrupt("return");
467
+ return _context8.abrupt("return");
522
468
  case 1:
523
469
  draining = true;
524
- _context9.prev = 2;
525
- _context9.next = 3;
526
- return readyPromise;
470
+ _context8.prev = 2;
527
471
  case 3:
528
472
  if (!(!destroyed && queue.length)) {
529
- _context9.next = 10;
473
+ _context8.next = 10;
530
474
  break;
531
475
  }
532
476
  if (setExternalEventFn) {
533
- _context9.next = 5;
477
+ _context8.next = 5;
534
478
  break;
535
479
  }
536
- _context9.next = 4;
480
+ _context8.next = 4;
537
481
  return nextFrame();
538
482
  case 4:
539
- return _context9.abrupt("continue", 3);
483
+ return _context8.abrupt("continue", 3);
540
484
  case 5:
541
485
  item = queue.shift();
542
486
  if (!(item && item.__marker === MARKER)) {
543
- _context9.next = 6;
487
+ _context8.next = 6;
544
488
  break;
545
489
  }
546
490
  pendingMarkers["delete"](item.token);
547
- return _context9.abrupt("continue", 3);
491
+ return _context8.abrupt("continue", 3);
548
492
  case 6:
549
- _context9.prev = 6;
493
+ _context8.prev = 6;
550
494
  setExternalEventFn(item);
551
- _context9.next = 7;
495
+ _context8.next = 7;
552
496
  return settle(item);
553
497
  case 7:
554
- _context9.next = 9;
498
+ _context8.next = 9;
555
499
  break;
556
500
  case 8:
557
- _context9.prev = 8;
558
- _t = _context9["catch"](6);
559
- error('drain:event failed', {
560
- err: (_err$message = _t === null || _t === void 0 ? void 0 : _t.message) !== null && _err$message !== void 0 ? _err$message : _t,
561
- type: item === null || item === void 0 ? void 0 : item.type
562
- });
501
+ _context8.prev = 8;
502
+ _t = _context8["catch"](6);
503
+ console.error('[kitchen-simulator] event failed:', item, _t);
504
+ // IMPORTANT: continue so we can eventually consume the marker
505
+ // Optionally you can decide to clear remaining queue here.
563
506
  case 9:
564
- _context9.next = 3;
507
+ _context8.next = 3;
565
508
  break;
566
509
  case 10:
567
- _context9.prev = 10;
510
+ _context8.prev = 10;
568
511
  draining = false;
569
- return _context9.finish(10);
512
+ return _context8.finish(10);
570
513
  case 11:
571
514
  case "end":
572
- return _context9.stop();
515
+ return _context8.stop();
573
516
  }
574
- }, _callee9, null, [[2,, 10, 11], [6, 8]]);
517
+ }, _callee8, null, [[2,, 10, 11], [6, 8]]);
575
518
  }));
576
519
  return _drain.apply(this, arguments);
577
520
  }
@@ -590,64 +533,29 @@ export function renderKitchenSimulator(container) {
590
533
  return _createClass(Wrapper, [{
591
534
  key: "componentDidMount",
592
535
  value: function componentDidMount() {
593
- var _this3 = this;
536
+ var _this3 = this,
537
+ _resolveReady;
594
538
  this._mounted = true;
595
- log('Wrapper mounted -> ready');
596
539
  setExternalEventFn = function setExternalEventFn(newEvent) {
597
540
  if (!_this3._mounted) return;
598
541
  _this3.setState({
599
542
  externalEvent: newEvent
600
543
  });
601
544
  };
602
- if (readyResolve) {
603
- readyResolve(true);
604
- readyResolve = null;
605
- }
545
+ (_resolveReady = resolveReady) === null || _resolveReady === void 0 || _resolveReady();
546
+ resolveReady = null;
547
+ drain(); // now it can actually process queued events
606
548
  }
607
549
  }, {
608
550
  key: "componentWillUnmount",
609
551
  value: function componentWillUnmount() {
610
552
  this._mounted = false;
611
553
  setExternalEventFn = null;
612
- if (readyReject) {
613
- readyReject(new Error('Wrapper unmounted before ready'));
614
- readyReject = null;
615
- }
616
554
  }
617
555
  }, {
618
556
  key: "render",
619
557
  value: function render() {
620
- var userOnInternalEvent = this.props.onInternalEvent;
621
-
622
- // ✅ Wrap internal event to detect catalog readiness
623
- var onInternalEventWrapped = /*#__PURE__*/function () {
624
- var _ref5 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee6(evt, callback) {
625
- return _regeneratorRuntime.wrap(function (_context6) {
626
- while (1) switch (_context6.prev = _context6.next) {
627
- case 0:
628
- // IMPORTANT: first time we see INTERNAL_EVENT_ITEMS_CATALOG,
629
- // it means catalog init path ran and tool is requesting items.
630
- if (!catalogReady && (evt === null || evt === void 0 ? void 0 : evt.type) === 'INTERNAL_EVENT_ITEMS_CATALOG') {
631
- catalogReady = true;
632
- if (catalogReadyResolve) {
633
- catalogReadyResolve(true);
634
- catalogReadyResolve = null;
635
- }
636
- log('Catalog is ready (observed INTERNAL_EVENT_ITEMS_CATALOG)');
637
- }
638
- return _context6.abrupt("return", userOnInternalEvent === null || userOnInternalEvent === void 0 ? void 0 : userOnInternalEvent(evt, callback));
639
- case 1:
640
- case "end":
641
- return _context6.stop();
642
- }
643
- }, _callee6);
644
- }));
645
- return function onInternalEventWrapped(_x3, _x4) {
646
- return _ref5.apply(this, arguments);
647
- };
648
- }();
649
558
  return /*#__PURE__*/React.createElement(LiteRenderer, _extends({}, this.props, {
650
- onInternalEvent: onInternalEventWrapped,
651
559
  externalEvent: this.state.externalEvent
652
560
  }));
653
561
  }
@@ -657,26 +565,22 @@ export function renderKitchenSimulator(container) {
657
565
  __render: function __render(nextProps) {
658
566
  root.render(/*#__PURE__*/React.createElement(Wrapper, nextProps));
659
567
  },
660
- // ✅ Host can await mount
661
568
  whenReady: function whenReady() {
662
569
  return readyPromise;
663
570
  },
664
- // ✅ Host can await catalog init (NEW)
665
- whenCatalogReady: function whenCatalogReady() {
666
- return catalogReadyPromise;
667
- },
571
+ // ✅ host can query current inFlight
668
572
  getGltfInFlight: function getGltfInFlight() {
669
573
  return gltfTracker.getInFlight();
670
574
  },
575
+ // ✅ host can subscribe to inFlight changes (loader)
671
576
  subscribeGltfInFlight: function subscribeGltfInFlight(cb) {
672
577
  return gltfTracker.subscribe(cb);
673
578
  },
674
579
  sendExternalEvents: function sendExternalEvents(eventOrEvents) {
675
- var _ref6 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
676
- _ref6$timeoutMs = _ref6.timeoutMs,
677
- timeoutMs = _ref6$timeoutMs === void 0 ? 60000 : _ref6$timeoutMs;
580
+ var _ref5 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
581
+ _ref5$timeoutMs = _ref5.timeoutMs,
582
+ timeoutMs = _ref5$timeoutMs === void 0 ? 60000 : _ref5$timeoutMs;
678
583
  var events = Array.isArray(eventOrEvents) ? eventOrEvents : [eventOrEvents];
679
- var token = Symbol('batch');
680
584
  var _iterator2 = _createForOfIteratorHelper(events),
681
585
  _step2;
682
586
  try {
@@ -689,69 +593,85 @@ export function renderKitchenSimulator(container) {
689
593
  } finally {
690
594
  _iterator2.f();
691
595
  }
596
+ var token = Symbol('batch');
692
597
  pendingMarkers.add(token);
693
598
  queue.push({
694
599
  __marker: MARKER,
695
600
  token: token
696
601
  });
697
- drain();
602
+ if (setExternalEventFn) drain();
603
+
604
+ // resolve when marker cleared
698
605
  return new Promise(function (resolve) {
699
606
  var start = Date.now();
700
607
  var check = /*#__PURE__*/function () {
701
- var _ref7 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee7() {
702
- return _regeneratorRuntime.wrap(function (_context7) {
703
- while (1) switch (_context7.prev = _context7.next) {
608
+ var _ref6 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee6() {
609
+ return _regeneratorRuntime.wrap(function (_context6) {
610
+ while (1) switch (_context6.prev = _context6.next) {
704
611
  case 0:
705
612
  if (destroyed) {
706
- _context7.next = 4;
613
+ _context6.next = 4;
707
614
  break;
708
615
  }
709
616
  if (pendingMarkers.has(token)) {
710
- _context7.next = 1;
617
+ _context6.next = 1;
711
618
  break;
712
619
  }
713
620
  resolve(true);
714
- return _context7.abrupt("return");
621
+ return _context6.abrupt("return");
715
622
  case 1:
716
623
  if (!(Date.now() - start > timeoutMs)) {
717
- _context7.next = 2;
624
+ _context6.next = 2;
718
625
  break;
719
626
  }
720
- error('sendExternalEvents timed out', {
721
- timeoutMs: timeoutMs
722
- });
627
+ console.error('[kitchen-simulator] sendExternalEvents timed out');
723
628
  pendingMarkers["delete"](token); // fail-open
724
629
  resolve(false);
725
- return _context7.abrupt("return");
630
+ return _context6.abrupt("return");
726
631
  case 2:
727
- _context7.next = 3;
632
+ _context6.next = 3;
728
633
  return nextFrame();
729
634
  case 3:
730
- _context7.next = 0;
635
+ _context6.next = 0;
731
636
  break;
732
637
  case 4:
733
638
  resolve(false);
734
639
  case 5:
735
640
  case "end":
736
- return _context7.stop();
641
+ return _context6.stop();
737
642
  }
738
- }, _callee7);
643
+ }, _callee6);
739
644
  }));
740
645
  return function check() {
741
- return _ref7.apply(this, arguments);
646
+ return _ref6.apply(this, arguments);
742
647
  };
743
648
  }();
744
649
  check();
745
650
  });
746
651
  },
747
- unmount: function unmount() {
748
- destroyed = true;
652
+ updateExternalEvent: function updateExternalEvent(e) {
653
+ return api.sendExternalEvents(e);
654
+ },
655
+ clearQueue: function clearQueue() {
749
656
  queue.length = 0;
750
657
  pendingMarkers.clear();
658
+ },
659
+ unmount: function unmount() {
660
+ var _resolveReady2;
661
+ destroyed = true;
662
+ api.clearQueue();
751
663
  gltfTracker.uninstall();
752
- root.unmount();
753
- container[ROOT_KEY] = null;
754
- container[API_KEY] = null;
664
+ (_resolveReady2 = resolveReady) === null || _resolveReady2 === void 0 || _resolveReady2();
665
+ resolveReady = null;
666
+ var doUnmount = function doUnmount() {
667
+ try {
668
+ root.unmount();
669
+ } finally {
670
+ container[ROOT_KEY] = null;
671
+ container[API_KEY] = null;
672
+ }
673
+ };
674
+ if (typeof queueMicrotask === 'function') queueMicrotask(doUnmount);else setTimeout(doUnmount, 0);
755
675
  }
756
676
  };
757
677
  api.__render(props);
@@ -23,6 +23,9 @@ export default function (state, action) {
23
23
  case UPDATE_POPUP_OPEN:
24
24
  return Item.updatePopupOpen(state, action.value).updatedState;
25
25
  case SELECT_ITEM:
26
+ state = state.merge({
27
+ sceneHistory: history.historyPush(state.sceneHistory, state.scene)
28
+ });
26
29
  return Item.select(state, action.layerID, action.itemID).updatedState;
27
30
  case SELECT_TOOL_DRAWING_ITEM:
28
31
  state = state.merge({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kitchen-simulator",
3
- "version": "6.0.3-react.18",
3
+ "version": "7.0.1-react-18",
4
4
  "description": "It is a kitchen simulator (self-contained micro-frontend).",
5
5
  "license": "MIT",
6
6
  "module": "es/index.js",