kitchen-simulator 6.0.1-react.18 → 6.0.3-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.
Files changed (2) hide show
  1. package/es/index.js +530 -234
  2. package/package.json +1 -1
package/es/index.js CHANGED
@@ -5,42 +5,95 @@ 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";
8
9
  function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
9
10
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
10
11
  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; } } }; }
11
12
  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; } }
12
13
  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; }
13
14
  import _regeneratorRuntime from "@babel/runtime/regenerator";
15
+ // kitchen-simulator/index.js (or wherever renderKitchenSimulator lives)
14
16
  import React from 'react';
15
- import * as Three from 'three';
16
- import LiteRenderer from "./LiteRenderer";
17
17
  import { createRoot } from 'react-dom/client';
18
+ import LiteRenderer from "./LiteRenderer";
19
+ import * as Three from 'three';
18
20
  var ROOT_KEY = '__kitchenSimulatorRoot__';
19
21
  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
+ };
70
+ }
20
71
 
21
- // ---------------- URL rewrite (keep if needed) ----------------
72
+ // ---- Your URL rewrite + TextureLoader patch stays as you had it ----
22
73
  var API_HOST_REGEX = /(https?:\/\/)?(api\.diydesignspace\.com|api\.addovisuals\.com|127\.0\.0\.1:4002)/;
23
74
  var API_HOST_REPLACEMENT = 'https://api-old.diydesignspace.com';
24
75
  function rewriteApiUrl(url) {
25
76
  return typeof url === 'string' ? url.replace(API_HOST_REGEX, API_HOST_REPLACEMENT) : url;
26
77
  }
27
-
28
- // texture rewrite
29
78
  var originalTextureLoad = Three.TextureLoader.prototype.load;
30
79
  Three.TextureLoader.prototype.load = function (url, onLoad, onProgress, onError) {
31
- return originalTextureLoad.call(this, rewriteApiUrl(url), onLoad, onProgress, onError);
80
+ var newUrl = rewriteApiUrl(url);
81
+ return originalTextureLoad.call(this, newUrl, onLoad, onProgress, onError);
32
82
  };
33
83
 
34
- // ---------------- minimal gltf tracker (same idea, but smaller) ----------------
84
+ /**
85
+ * Track 3D asset network activity (gltf/glb/bin/textures/hdr/etc)
86
+ * Ref-counted global install so multiple instances don't clobber each other.
87
+ */
35
88
  function installGltfTracker() {
36
89
  if (typeof window === 'undefined') {
90
+ var _subscribe = function _subscribe() {
91
+ return function () {};
92
+ };
37
93
  return {
38
94
  getInFlight: function getInFlight() {
39
95
  return 0;
40
96
  },
41
- subscribe: function subscribe() {
42
- return function () {};
43
- },
44
97
  waitForIdle: function () {
45
98
  var _waitForIdle = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
46
99
  return _regeneratorRuntime.wrap(function (_context) {
@@ -58,25 +111,32 @@ function installGltfTracker() {
58
111
  }
59
112
  return waitForIdle;
60
113
  }(),
61
- uninstall: function uninstall() {}
114
+ uninstall: function uninstall() {},
115
+ subscribe: _subscribe
62
116
  };
63
117
  }
64
- var KEY = '__kitchenSimulatorGltfTracker__';
65
- if (!window[KEY]) {
66
- window[KEY] = {
118
+ var GLOBAL_KEY = '__kitchenSimulatorGltfTracker__';
119
+ if (!window[GLOBAL_KEY]) {
120
+ window[GLOBAL_KEY] = {
67
121
  refCount: 0,
68
122
  inFlight: 0,
69
123
  listeners: new Set(),
70
124
  installed: false,
71
- originalFetch: null
125
+ originalFetch: null,
126
+ originalOpen: null,
127
+ originalSend: null
72
128
  };
73
129
  }
74
- var g = window[KEY];
130
+ var g = window[GLOBAL_KEY];
75
131
  var is3dAssetUrl = function is3dAssetUrl(url) {
76
- var _ref, _url$url, _url$toString;
77
- var s = typeof url === 'string' ? url : (_ref = (_url$url = url === null || url === void 0 ? void 0 : url.url) !== null && _url$url !== void 0 ? _url$url : url === null || url === void 0 || (_url$toString = url.toString) === null || _url$toString === void 0 ? void 0 : _url$toString.call(url)) !== null && _ref !== void 0 ? _ref : '';
78
- var u = String(s).toLowerCase().split('?')[0];
79
- 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');
132
+ try {
133
+ var _url$toString, _url$toString2;
134
+ 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
+ var u = s.toLowerCase().split('?')[0]; // ignore cache params
136
+ 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) {
138
+ return false;
139
+ }
80
140
  };
81
141
  var notify = function notify() {
82
142
  var _iterator = _createForOfIteratorHelper(g.listeners),
@@ -94,16 +154,110 @@ function installGltfTracker() {
94
154
  };
95
155
  var subscribe = function subscribe(fn) {
96
156
  g.listeners.add(fn);
97
- fn(g.inFlight);
157
+ fn(g.inFlight); // sync emit on subscribe
98
158
  return function () {
99
159
  return g.listeners["delete"](fn);
100
160
  };
101
161
  };
102
- var nextFrame = function nextFrame() {
103
- return new Promise(function (r) {
104
- return requestAnimationFrame(r);
105
- });
162
+ var installIfNeeded = function installIfNeeded() {
163
+ var _XHR$prototype, _XHR$prototype2;
164
+ if (g.installed) return;
165
+
166
+ // ---- XHR hook ----
167
+ var XHR = window.XMLHttpRequest;
168
+ 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) {
169
+ g.originalOpen = XHR.prototype.open;
170
+ g.originalSend = XHR.prototype.send;
171
+ XHR.prototype.open = function (method, url) {
172
+ var _g$originalOpen;
173
+ 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];
176
+ }
177
+ return (_g$originalOpen = g.originalOpen).call.apply(_g$originalOpen, [this, method, url].concat(rest));
178
+ };
179
+ XHR.prototype.send = function () {
180
+ var _this = this;
181
+ if (this.__is3dAssetRequest) {
182
+ g.inFlight += 1;
183
+ notify();
184
+ var _done = function done() {
185
+ g.inFlight -= 1;
186
+ if (g.inFlight < 0) g.inFlight = 0;
187
+ notify();
188
+ _this.removeEventListener('loadend', _done);
189
+ _this.removeEventListener('error', _done);
190
+ _this.removeEventListener('abort', _done);
191
+ _this.removeEventListener('timeout', _done);
192
+ };
193
+ this.addEventListener('loadend', _done);
194
+ this.addEventListener('error', _done);
195
+ this.addEventListener('abort', _done);
196
+ this.addEventListener('timeout', _done);
197
+ }
198
+ for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
199
+ args[_key5] = arguments[_key5];
200
+ }
201
+ return g.originalSend.apply(this, args);
202
+ };
203
+ }
204
+
205
+ // ---- fetch hook ----
206
+ g.originalFetch = window.fetch;
207
+ if (typeof g.originalFetch === 'function') {
208
+ window.fetch = /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
209
+ var _len6,
210
+ args,
211
+ _key6,
212
+ input,
213
+ init,
214
+ newUrl,
215
+ track,
216
+ _args2 = arguments;
217
+ return _regeneratorRuntime.wrap(function (_context2) {
218
+ while (1) switch (_context2.prev = _context2.next) {
219
+ case 0:
220
+ for (_len6 = _args2.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
221
+ args[_key6] = _args2[_key6];
222
+ }
223
+ input = args[0], init = args[1]; // DIY-714 [Temp Fix] Rewrite API URLs
224
+ if (typeof input === 'string') {
225
+ input = rewriteApiUrl(input);
226
+ } else if (input instanceof Request) {
227
+ newUrl = rewriteApiUrl(input.url);
228
+ input = new Request(newUrl, input);
229
+ }
230
+ track = is3dAssetUrl(input);
231
+ if (track) {
232
+ _context2.next = 1;
233
+ break;
234
+ }
235
+ return _context2.abrupt("return", g.originalFetch.call(this, input, init));
236
+ case 1:
237
+ g.inFlight += 1;
238
+ notify();
239
+ _context2.prev = 2;
240
+ _context2.next = 3;
241
+ return g.originalFetch.call(this, input, init);
242
+ case 3:
243
+ return _context2.abrupt("return", _context2.sent);
244
+ case 4:
245
+ _context2.prev = 4;
246
+ g.inFlight -= 1;
247
+ if (g.inFlight < 0) g.inFlight = 0;
248
+ notify();
249
+ return _context2.finish(4);
250
+ case 5:
251
+ case "end":
252
+ return _context2.stop();
253
+ }
254
+ }, _callee2, this, [[2,, 4, 5]]);
255
+ }));
256
+ }
257
+ g.installed = true;
106
258
  };
259
+
260
+ // “No grace” but stable: idle must remain idle for 2 RAF frames
107
261
  function waitStableIdle2Frames() {
108
262
  return _waitStableIdle2Frames.apply(this, arguments);
109
263
  }
@@ -134,138 +288,106 @@ function installGltfTracker() {
134
288
  return _waitStableIdle2Frames.apply(this, arguments);
135
289
  }
136
290
  var waitForIdle = /*#__PURE__*/function () {
137
- var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
291
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
138
292
  var _ref3,
139
293
  _ref3$timeoutMs,
140
294
  timeoutMs,
141
- _args3 = arguments;
142
- return _regeneratorRuntime.wrap(function (_context3) {
143
- while (1) switch (_context3.prev = _context3.next) {
295
+ _args4 = arguments;
296
+ return _regeneratorRuntime.wrap(function (_context4) {
297
+ while (1) switch (_context4.prev = _context4.next) {
144
298
  case 0:
145
- _ref3 = _args3.length > 0 && _args3[0] !== undefined ? _args3[0] : {}, _ref3$timeoutMs = _ref3.timeoutMs, timeoutMs = _ref3$timeoutMs === void 0 ? 30000 : _ref3$timeoutMs;
146
- _context3.next = 1;
299
+ _ref3 = _args4.length > 0 && _args4[0] !== undefined ? _args4[0] : {}, _ref3$timeoutMs = _ref3.timeoutMs, timeoutMs = _ref3$timeoutMs === void 0 ? 30000 : _ref3$timeoutMs;
300
+ _context4.next = 1;
147
301
  return waitStableIdle2Frames();
148
302
  case 1:
149
- if (!_context3.sent) {
150
- _context3.next = 2;
303
+ if (!_context4.sent) {
304
+ _context4.next = 2;
151
305
  break;
152
306
  }
153
- return _context3.abrupt("return", true);
307
+ return _context4.abrupt("return", true);
154
308
  case 2:
155
- return _context3.abrupt("return", new Promise(function (resolve, reject) {
156
- var done = false;
309
+ return _context4.abrupt("return", new Promise(function (resolve, reject) {
310
+ var unsub = null;
311
+ var finished = false;
312
+ var finishOk = function finishOk() {
313
+ if (finished) return;
314
+ finished = true;
315
+ if (unsub) unsub();
316
+ clearTimeout(timer);
317
+ resolve(true);
318
+ };
319
+ var finishErr = function finishErr(err) {
320
+ if (finished) return;
321
+ finished = true;
322
+ if (unsub) unsub();
323
+ clearTimeout(timer);
324
+ reject(err);
325
+ };
326
+
327
+ // ✅ Real timeout no matter what happens with inFlight changes
157
328
  var timer = setTimeout(function () {
158
- if (done) return;
159
- done = true;
160
- unsub === null || unsub === void 0 || unsub();
161
- reject(new Error('3D assets did not become idle within timeout'));
329
+ finishErr(new Error('3D assets did not become idle within timeout'));
162
330
  }, timeoutMs);
163
- var unsub = subscribe(/*#__PURE__*/function () {
164
- var _ref4 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(count) {
331
+ var onChange = /*#__PURE__*/function () {
332
+ var _ref4 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(count) {
165
333
  var stable;
166
- return _regeneratorRuntime.wrap(function (_context2) {
167
- while (1) switch (_context2.prev = _context2.next) {
334
+ return _regeneratorRuntime.wrap(function (_context3) {
335
+ while (1) switch (_context3.prev = _context3.next) {
168
336
  case 0:
169
- if (!done) {
170
- _context2.next = 1;
337
+ if (!finished) {
338
+ _context3.next = 1;
171
339
  break;
172
340
  }
173
- return _context2.abrupt("return");
341
+ return _context3.abrupt("return");
174
342
  case 1:
175
343
  if (!(count !== 0)) {
176
- _context2.next = 2;
344
+ _context3.next = 2;
177
345
  break;
178
346
  }
179
- return _context2.abrupt("return");
347
+ return _context3.abrupt("return");
180
348
  case 2:
181
- _context2.next = 3;
349
+ _context3.next = 3;
182
350
  return waitStableIdle2Frames();
183
351
  case 3:
184
- stable = _context2.sent;
185
- if (stable) {
186
- done = true;
187
- clearTimeout(timer);
188
- unsub();
189
- resolve(true);
190
- }
352
+ stable = _context3.sent;
353
+ if (stable) finishOk();
354
+ // else keep waiting
191
355
  case 4:
192
356
  case "end":
193
- return _context2.stop();
357
+ return _context3.stop();
194
358
  }
195
- }, _callee2);
359
+ }, _callee3);
196
360
  }));
197
- return function (_x) {
361
+ return function onChange(_x) {
198
362
  return _ref4.apply(this, arguments);
199
363
  };
200
- }());
364
+ }();
365
+ unsub = subscribe(onChange);
201
366
  }));
202
367
  case 3:
203
368
  case "end":
204
- return _context3.stop();
369
+ return _context4.stop();
205
370
  }
206
- }, _callee3);
371
+ }, _callee4);
207
372
  }));
208
373
  return function waitForIdle() {
209
374
  return _ref2.apply(this, arguments);
210
375
  };
211
376
  }();
212
- var installIfNeeded = function installIfNeeded() {
213
- if (g.installed) return;
214
- g.originalFetch = window.fetch;
215
- if (typeof g.originalFetch === 'function') {
216
- window.fetch = /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
217
- var _len,
218
- args,
219
- _key,
220
- input,
221
- init,
222
- track,
223
- _args4 = arguments;
224
- return _regeneratorRuntime.wrap(function (_context4) {
225
- while (1) switch (_context4.prev = _context4.next) {
226
- case 0:
227
- for (_len = _args4.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
228
- args[_key] = _args4[_key];
229
- }
230
- input = args[0], init = args[1]; // rewrite
231
- if (typeof input === 'string') input = rewriteApiUrl(input);else if (input instanceof Request) input = new Request(rewriteApiUrl(input.url), input);
232
- track = is3dAssetUrl(input);
233
- if (track) {
234
- _context4.next = 1;
235
- break;
236
- }
237
- return _context4.abrupt("return", g.originalFetch.call(this, input, init));
238
- case 1:
239
- g.inFlight += 1;
240
- notify();
241
- _context4.prev = 2;
242
- _context4.next = 3;
243
- return g.originalFetch.call(this, input, init);
244
- case 3:
245
- return _context4.abrupt("return", _context4.sent);
246
- case 4:
247
- _context4.prev = 4;
248
- g.inFlight -= 1;
249
- if (g.inFlight < 0) g.inFlight = 0;
250
- notify();
251
- return _context4.finish(4);
252
- case 5:
253
- case "end":
254
- return _context4.stop();
255
- }
256
- }, _callee4, this, [[2,, 4, 5]]);
257
- }));
258
- }
259
- g.installed = true;
260
- };
261
377
  var uninstall = function uninstall() {
378
+ var _XHR$prototype3, _XHR$prototype4;
262
379
  g.refCount -= 1;
263
380
  if (g.refCount > 0) return;
381
+ var XHR = window.XMLHttpRequest;
382
+ 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;
383
+ 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;
264
384
  if (typeof g.originalFetch === 'function') window.fetch = g.originalFetch;
265
385
  g.listeners.clear();
266
386
  g.inFlight = 0;
267
387
  g.installed = false;
268
388
  g.originalFetch = null;
389
+ g.originalOpen = null;
390
+ g.originalSend = null;
269
391
  };
270
392
  g.refCount += 1;
271
393
  installIfNeeded();
@@ -273,76 +395,259 @@ function installGltfTracker() {
273
395
  getInFlight: function getInFlight() {
274
396
  return g.inFlight;
275
397
  },
276
- subscribe: subscribe,
277
398
  waitForIdle: waitForIdle,
278
- uninstall: uninstall
399
+ uninstall: uninstall,
400
+ subscribe: subscribe
279
401
  };
280
402
  }
281
-
282
- // ---------------- simple render + simple API ----------------
283
403
  export function renderKitchenSimulator(container) {
404
+ var _props$framesPerEvent, _props$waitForGltfIdl, _props$gltfTimeoutMs;
284
405
  var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
285
406
  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;
286
415
 
287
- // reuse API if already mounted
416
+ // Reuse existing API
288
417
  if (container[API_KEY]) {
289
- container[API_KEY].__render(props);
418
+ var _container$API_KEY$__, _container$API_KEY;
419
+ log('Reusing existing API; calling __render with new props');
420
+ (_container$API_KEY$__ = (_container$API_KEY = container[API_KEY]).__render) === null || _container$API_KEY$__ === void 0 || _container$API_KEY$__.call(_container$API_KEY, props);
290
421
  return container[API_KEY];
291
422
  }
292
423
 
293
- // reuse root
424
+ // Root
294
425
  var root = container[ROOT_KEY];
295
426
  if (!root) {
296
427
  root = createRoot(container);
297
428
  container[ROOT_KEY] = root;
429
+ log('Created new React root');
298
430
  }
299
- var gltfTracker = installGltfTracker();
431
+ var setExternalEventFn = null;
300
432
  var destroyed = false;
301
- var setExternalEvent = null;
433
+ var queue = [];
434
+ var pendingMarkers = new Set();
435
+ var MARKER = Symbol('marker');
436
+
437
+ // ✅ keep your tracker
438
+ var gltfTracker = installGltfTracker(debugEnabled);
439
+ var defaultFramesPerEvent = (_props$framesPerEvent = props.framesPerEvent) !== null && _props$framesPerEvent !== void 0 ? _props$framesPerEvent : 1;
440
+ var waitForAssets = (_props$waitForGltfIdl = props.waitForGltfIdleAfterEachEvent) !== null && _props$waitForGltfIdl !== void 0 ? _props$waitForGltfIdl : true;
441
+ var defaultTimeout = (_props$gltfTimeoutMs = props.gltfTimeoutMs) !== null && _props$gltfTimeoutMs !== void 0 ? _props$gltfTimeoutMs : 30000;
442
+ var draining = false;
302
443
 
303
- // mounted gate (first-event safety)
304
- var mountedResolve;
305
- var mounted = new Promise(function (res) {
306
- return mountedResolve = res;
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;
307
450
  });
308
- var nextFrame = function nextFrame() {
309
- return new Promise(function (r) {
310
- return requestAnimationFrame(r);
451
+
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);
311
461
  });
312
- };
462
+ }
463
+ function settle(_x2) {
464
+ return _settle.apply(this, arguments);
465
+ }
466
+ 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) {
472
+ 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
476
+ i = 0;
477
+ case 1:
478
+ if (!(i < frames)) {
479
+ _context8.next = 3;
480
+ break;
481
+ }
482
+ _context8.next = 2;
483
+ return nextFrame();
484
+ case 2:
485
+ i++;
486
+ _context8.next = 1;
487
+ break;
488
+ case 3:
489
+ if (!shouldWait) {
490
+ _context8.next = 4;
491
+ break;
492
+ }
493
+ _context8.next = 4;
494
+ return gltfTracker.waitForIdle({
495
+ timeoutMs: timeoutMs
496
+ });
497
+ case 4:
498
+ _context8.next = 5;
499
+ return nextFrame();
500
+ case 5:
501
+ case "end":
502
+ return _context8.stop();
503
+ }
504
+ }, _callee8);
505
+ }));
506
+ return _settle.apply(this, arguments);
507
+ }
508
+ function drain() {
509
+ return _drain.apply(this, arguments);
510
+ }
511
+ 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) {
516
+ case 0:
517
+ if (!(draining || destroyed)) {
518
+ _context9.next = 1;
519
+ break;
520
+ }
521
+ return _context9.abrupt("return");
522
+ case 1:
523
+ draining = true;
524
+ _context9.prev = 2;
525
+ _context9.next = 3;
526
+ return readyPromise;
527
+ case 3:
528
+ if (!(!destroyed && queue.length)) {
529
+ _context9.next = 10;
530
+ break;
531
+ }
532
+ if (setExternalEventFn) {
533
+ _context9.next = 5;
534
+ break;
535
+ }
536
+ _context9.next = 4;
537
+ return nextFrame();
538
+ case 4:
539
+ return _context9.abrupt("continue", 3);
540
+ case 5:
541
+ item = queue.shift();
542
+ if (!(item && item.__marker === MARKER)) {
543
+ _context9.next = 6;
544
+ break;
545
+ }
546
+ pendingMarkers["delete"](item.token);
547
+ return _context9.abrupt("continue", 3);
548
+ case 6:
549
+ _context9.prev = 6;
550
+ setExternalEventFn(item);
551
+ _context9.next = 7;
552
+ return settle(item);
553
+ case 7:
554
+ _context9.next = 9;
555
+ break;
556
+ 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
+ });
563
+ case 9:
564
+ _context9.next = 3;
565
+ break;
566
+ case 10:
567
+ _context9.prev = 10;
568
+ draining = false;
569
+ return _context9.finish(10);
570
+ case 11:
571
+ case "end":
572
+ return _context9.stop();
573
+ }
574
+ }, _callee9, null, [[2,, 10, 11], [6, 8]]);
575
+ }));
576
+ return _drain.apply(this, arguments);
577
+ }
313
578
  var Wrapper = /*#__PURE__*/function (_React$Component) {
314
579
  function Wrapper(p) {
315
- var _this;
580
+ var _this2;
316
581
  _classCallCheck(this, Wrapper);
317
- _this = _callSuper(this, Wrapper, [p]);
318
- _this.state = {
319
- externalEvent: null
582
+ _this2 = _callSuper(this, Wrapper, [p]);
583
+ _this2.state = {
584
+ externalEvent: p.externalEvent || null
320
585
  };
321
- return _this;
586
+ _this2._mounted = false;
587
+ return _this2;
322
588
  }
323
589
  _inherits(Wrapper, _React$Component);
324
590
  return _createClass(Wrapper, [{
325
591
  key: "componentDidMount",
326
592
  value: function componentDidMount() {
327
- var _this2 = this,
328
- _mountedResolve;
329
- setExternalEvent = function setExternalEvent(ev) {
330
- return _this2.setState({
331
- externalEvent: ev
593
+ var _this3 = this;
594
+ this._mounted = true;
595
+ log('Wrapper mounted -> ready');
596
+ setExternalEventFn = function setExternalEventFn(newEvent) {
597
+ if (!_this3._mounted) return;
598
+ _this3.setState({
599
+ externalEvent: newEvent
332
600
  });
333
601
  };
334
- (_mountedResolve = mountedResolve) === null || _mountedResolve === void 0 || _mountedResolve();
335
- mountedResolve = null;
602
+ if (readyResolve) {
603
+ readyResolve(true);
604
+ readyResolve = null;
605
+ }
336
606
  }
337
607
  }, {
338
608
  key: "componentWillUnmount",
339
609
  value: function componentWillUnmount() {
340
- setExternalEvent = null;
610
+ this._mounted = false;
611
+ setExternalEventFn = null;
612
+ if (readyReject) {
613
+ readyReject(new Error('Wrapper unmounted before ready'));
614
+ readyReject = null;
615
+ }
341
616
  }
342
617
  }, {
343
618
  key: "render",
344
619
  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
+ }();
345
649
  return /*#__PURE__*/React.createElement(LiteRenderer, _extends({}, this.props, {
650
+ onInternalEvent: onInternalEventWrapped,
346
651
  externalEvent: this.state.externalEvent
347
652
  }));
348
653
  }
@@ -352,106 +657,97 @@ export function renderKitchenSimulator(container) {
352
657
  __render: function __render(nextProps) {
353
658
  root.render(/*#__PURE__*/React.createElement(Wrapper, nextProps));
354
659
  },
355
- // subscribe to gltf inFlight
356
- subscribeGltfInFlight: function subscribeGltfInFlight(cb) {
357
- return gltfTracker.subscribe(cb);
660
+ // Host can await mount
661
+ whenReady: function whenReady() {
662
+ return readyPromise;
663
+ },
664
+ // ✅ Host can await catalog init (NEW)
665
+ whenCatalogReady: function whenCatalogReady() {
666
+ return catalogReadyPromise;
358
667
  },
359
668
  getGltfInFlight: function getGltfInFlight() {
360
669
  return gltfTracker.getInFlight();
361
670
  },
362
- // VERY SIMPLE batch sender
363
- sendExternalEvents: function sendExternalEvents(events) {
364
- var _arguments = arguments;
365
- return _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee6() {
366
- var opts, _opts$framesPerEvent, framesPerEvent, _opts$heavyPredicate, heavyPredicate, _opts$gltfTimeoutMs, gltfTimeoutMs, list, _iterator2, _step2, ev, i, isHeavy, _t;
367
- return _regeneratorRuntime.wrap(function (_context6) {
368
- while (1) switch (_context6.prev = _context6.next) {
369
- case 0:
370
- opts = _arguments.length > 1 && _arguments[1] !== undefined ? _arguments[1] : {};
371
- _opts$framesPerEvent = opts.framesPerEvent, framesPerEvent = _opts$framesPerEvent === void 0 ? 2 : _opts$framesPerEvent, _opts$heavyPredicate = opts.heavyPredicate, heavyPredicate = _opts$heavyPredicate === void 0 ? function (ev) {
372
- var _ev$type;
373
- return /ADD_ITEM|LOAD_PROJECT|REPLACE|CHANGE_DOORSTYLE|SET_FINISHING|SET_MOLDING|ADD_ROOM_SHAPE/.test((_ev$type = ev === null || ev === void 0 ? void 0 : ev.type) !== null && _ev$type !== void 0 ? _ev$type : '');
374
- } : _opts$heavyPredicate, _opts$gltfTimeoutMs = opts.gltfTimeoutMs, gltfTimeoutMs = _opts$gltfTimeoutMs === void 0 ? 30000 : _opts$gltfTimeoutMs;
375
- list = Array.isArray(events) ? events : [events]; // ensure mounted before first event
376
- _context6.next = 1;
377
- return mounted;
378
- case 1:
379
- if (!(destroyed || !setExternalEvent)) {
380
- _context6.next = 2;
381
- break;
382
- }
383
- return _context6.abrupt("return", false);
384
- case 2:
385
- _iterator2 = _createForOfIteratorHelper(list);
386
- _context6.prev = 3;
387
- _iterator2.s();
388
- case 4:
389
- if ((_step2 = _iterator2.n()).done) {
390
- _context6.next = 11;
391
- break;
392
- }
393
- ev = _step2.value;
394
- if (!destroyed) {
395
- _context6.next = 5;
396
- break;
397
- }
398
- return _context6.abrupt("return", false);
399
- case 5:
400
- // push event
401
- setExternalEvent(ev);
402
-
403
- // allow react/redux to process
404
- i = 0;
405
- case 6:
406
- if (!(i < framesPerEvent)) {
407
- _context6.next = 8;
408
- break;
409
- }
410
- _context6.next = 7;
411
- return nextFrame();
412
- case 7:
413
- i++;
414
- _context6.next = 6;
415
- break;
416
- case 8:
417
- // optional gltf wait only for heavy events
418
- isHeavy = !!heavyPredicate(ev);
419
- if (!isHeavy) {
420
- _context6.next = 9;
421
- break;
671
+ subscribeGltfInFlight: function subscribeGltfInFlight(cb) {
672
+ return gltfTracker.subscribe(cb);
673
+ },
674
+ 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;
678
+ var events = Array.isArray(eventOrEvents) ? eventOrEvents : [eventOrEvents];
679
+ var token = Symbol('batch');
680
+ var _iterator2 = _createForOfIteratorHelper(events),
681
+ _step2;
682
+ try {
683
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
684
+ var e = _step2.value;
685
+ queue.push(e);
686
+ }
687
+ } catch (err) {
688
+ _iterator2.e(err);
689
+ } finally {
690
+ _iterator2.f();
691
+ }
692
+ pendingMarkers.add(token);
693
+ queue.push({
694
+ __marker: MARKER,
695
+ token: token
696
+ });
697
+ drain();
698
+ return new Promise(function (resolve) {
699
+ var start = Date.now();
700
+ 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) {
704
+ case 0:
705
+ if (destroyed) {
706
+ _context7.next = 4;
707
+ break;
708
+ }
709
+ if (pendingMarkers.has(token)) {
710
+ _context7.next = 1;
711
+ break;
712
+ }
713
+ resolve(true);
714
+ return _context7.abrupt("return");
715
+ case 1:
716
+ if (!(Date.now() - start > timeoutMs)) {
717
+ _context7.next = 2;
718
+ break;
719
+ }
720
+ error('sendExternalEvents timed out', {
721
+ timeoutMs: timeoutMs
722
+ });
723
+ pendingMarkers["delete"](token); // fail-open
724
+ resolve(false);
725
+ return _context7.abrupt("return");
726
+ case 2:
727
+ _context7.next = 3;
728
+ return nextFrame();
729
+ case 3:
730
+ _context7.next = 0;
731
+ break;
732
+ case 4:
733
+ resolve(false);
734
+ case 5:
735
+ case "end":
736
+ return _context7.stop();
422
737
  }
423
- _context6.next = 9;
424
- return gltfTracker.waitForIdle({
425
- timeoutMs: gltfTimeoutMs
426
- });
427
- case 9:
428
- _context6.next = 10;
429
- return nextFrame();
430
- case 10:
431
- _context6.next = 4;
432
- break;
433
- case 11:
434
- _context6.next = 13;
435
- break;
436
- case 12:
437
- _context6.prev = 12;
438
- _t = _context6["catch"](3);
439
- _iterator2.e(_t);
440
- case 13:
441
- _context6.prev = 13;
442
- _iterator2.f();
443
- return _context6.finish(13);
444
- case 14:
445
- return _context6.abrupt("return", true);
446
- case 15:
447
- case "end":
448
- return _context6.stop();
449
- }
450
- }, _callee6, null, [[3, 12, 13, 14]]);
451
- }))();
738
+ }, _callee7);
739
+ }));
740
+ return function check() {
741
+ return _ref7.apply(this, arguments);
742
+ };
743
+ }();
744
+ check();
745
+ });
452
746
  },
453
747
  unmount: function unmount() {
454
748
  destroyed = true;
749
+ queue.length = 0;
750
+ pendingMarkers.clear();
455
751
  gltfTracker.uninstall();
456
752
  root.unmount();
457
753
  container[ROOT_KEY] = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kitchen-simulator",
3
- "version": "6.0.1-react.18",
3
+ "version": "6.0.3-react.18",
4
4
  "description": "It is a kitchen simulator (self-contained micro-frontend).",
5
5
  "license": "MIT",
6
6
  "module": "es/index.js",