@preference-sl/pref-viewer 2.10.0-beta.23 → 2.10.0-beta.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/gltf-storage.js +10 -37
- package/src/index.js +91 -58
package/package.json
CHANGED
package/src/gltf-storage.js
CHANGED
|
@@ -12,52 +12,25 @@ function _getDbOrThrow() {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
// --- internal helpers -------------------------------------------------------
|
|
15
|
-
|
|
16
|
-
function _createStoreIfMissing(db, storeName) {
|
|
17
|
-
if (!db.objectStoreNames.contains(storeName)) {
|
|
18
|
-
const store = db.createObjectStore(storeName, { keyPath: "id" });
|
|
19
|
-
store.createIndex("expirationTimeStamp", "expirationTimeStamp", { unique: false });
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Opens a DB without specifying a version. If the required object store doesn't
|
|
25
|
-
* exist, it re-opens with (currentVersion + 1) to create it.
|
|
26
|
-
*/
|
|
27
15
|
function _openEnsuringStore(dbName, storeName) {
|
|
28
16
|
return new Promise((resolve, reject) => {
|
|
29
|
-
const open = indexedDB.open(dbName);
|
|
17
|
+
const open = indexedDB.open(dbName, 5);
|
|
30
18
|
|
|
31
19
|
open.onblocked = () => reject(new Error("Open blocked by another tab or worker"));
|
|
32
20
|
open.onerror = () => reject(open.error);
|
|
33
|
-
|
|
34
|
-
open.onupgradeneeded = (e) => {
|
|
35
|
-
// First creation path (brand-new DB)
|
|
36
|
-
const db = e.target.result;
|
|
37
|
-
_createStoreIfMissing(db, storeName);
|
|
38
|
-
};
|
|
39
|
-
|
|
40
21
|
open.onsuccess = (e) => {
|
|
41
|
-
|
|
22
|
+
resolve(e.target.result);
|
|
23
|
+
}
|
|
24
|
+
open.onupgradeneeded = (ev) => {
|
|
25
|
+
const upgradeDb = ev.target.result;
|
|
42
26
|
|
|
43
|
-
//
|
|
44
|
-
if (
|
|
45
|
-
|
|
46
|
-
return;
|
|
27
|
+
// Eliminar la object store si ya existe
|
|
28
|
+
if (upgradeDb.objectStoreNames.contains(storeName)) {
|
|
29
|
+
upgradeDb.deleteObjectStore(storeName);
|
|
47
30
|
}
|
|
48
31
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
db.close();
|
|
52
|
-
|
|
53
|
-
const upgrade = indexedDB.open(dbName, nextVersion);
|
|
54
|
-
upgrade.onblocked = () => reject(new Error("Upgrade blocked by another tab or worker"));
|
|
55
|
-
upgrade.onerror = () => reject(upgrade.error);
|
|
56
|
-
upgrade.onupgradeneeded = (ev) => {
|
|
57
|
-
const upDb = ev.target.result;
|
|
58
|
-
_createStoreIfMissing(upDb, storeName);
|
|
59
|
-
};
|
|
60
|
-
upgrade.onsuccess = (ev) => resolve(ev.target.result);
|
|
32
|
+
const store = upgradeDb.createObjectStore(storeName, { keyPath: 'id' });
|
|
33
|
+
store.createIndex('expirationTimeStamp', 'expirationTimeStamp', { unique: false });
|
|
61
34
|
};
|
|
62
35
|
});
|
|
63
36
|
}
|
package/src/index.js
CHANGED
|
@@ -61,7 +61,7 @@ class PrefViewer extends HTMLElement {
|
|
|
61
61
|
visible: false,
|
|
62
62
|
size: null,
|
|
63
63
|
timeStamp: null,
|
|
64
|
-
changed: false,
|
|
64
|
+
changed: { pending: false, success: false },
|
|
65
65
|
},
|
|
66
66
|
environment: {
|
|
67
67
|
name: "environment",
|
|
@@ -71,7 +71,7 @@ class PrefViewer extends HTMLElement {
|
|
|
71
71
|
visible: false,
|
|
72
72
|
size: null,
|
|
73
73
|
timeStamp: null,
|
|
74
|
-
changed: false,
|
|
74
|
+
changed: { pending: false, success: false },
|
|
75
75
|
},
|
|
76
76
|
materials: {
|
|
77
77
|
name: "materials",
|
|
@@ -81,35 +81,35 @@ class PrefViewer extends HTMLElement {
|
|
|
81
81
|
visible: false,
|
|
82
82
|
size: null,
|
|
83
83
|
timeStamp: null,
|
|
84
|
-
changed: false,
|
|
84
|
+
changed: { pending: false, success: false },
|
|
85
85
|
},
|
|
86
86
|
},
|
|
87
87
|
options: {
|
|
88
88
|
camera: {
|
|
89
89
|
value: null,
|
|
90
90
|
locked: true,
|
|
91
|
-
changed: false,
|
|
91
|
+
changed: { pending: false, success: false },
|
|
92
92
|
},
|
|
93
93
|
materials: {
|
|
94
94
|
innerWall: {
|
|
95
95
|
value: null,
|
|
96
96
|
prefix: "innerWall",
|
|
97
|
-
changed: false,
|
|
97
|
+
changed: { pending: false, success: false },
|
|
98
98
|
},
|
|
99
99
|
outerWall: {
|
|
100
100
|
value: null,
|
|
101
101
|
prefix: "outerWall",
|
|
102
|
-
changed: false,
|
|
102
|
+
changed: { pending: false, success: false },
|
|
103
103
|
},
|
|
104
104
|
innerFloor: {
|
|
105
105
|
value: null,
|
|
106
106
|
prefix: "innerFloor",
|
|
107
|
-
changed: false,
|
|
107
|
+
changed: { pending: false, success: false },
|
|
108
108
|
},
|
|
109
109
|
outerFloor: {
|
|
110
110
|
value: null,
|
|
111
111
|
prefix: "outerFloor",
|
|
112
|
-
changed: false,
|
|
112
|
+
changed: { pending: false, success: false },
|
|
113
113
|
},
|
|
114
114
|
},
|
|
115
115
|
},
|
|
@@ -261,24 +261,24 @@ class PrefViewer extends HTMLElement {
|
|
|
261
261
|
this.loading = false;
|
|
262
262
|
|
|
263
263
|
const toLoadDetail = {
|
|
264
|
-
container_model: !!this.#data.containers.model.changed,
|
|
265
|
-
container_environment: !!this.#data.containers.environment.changed,
|
|
266
|
-
container_materials: !!this.#data.containers.materials.changed,
|
|
267
|
-
options_camera: !!this.#data.options.camera.changed,
|
|
268
|
-
options_innerWallMaterial: !!this.#data.options.materials.innerWall.changed,
|
|
269
|
-
options_outerWallMaterial: !!this.#data.options.materials.outerWall.changed,
|
|
270
|
-
options_innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed,
|
|
271
|
-
options_outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed,
|
|
264
|
+
container_model: !!this.#data.containers.model.changed.pending,
|
|
265
|
+
container_environment: !!this.#data.containers.environment.changed.pending,
|
|
266
|
+
container_materials: !!this.#data.containers.materials.changed.pending,
|
|
267
|
+
options_camera: !!this.#data.options.camera.changed.pending,
|
|
268
|
+
options_innerWallMaterial: !!this.#data.options.materials.innerWall.changed.pending,
|
|
269
|
+
options_outerWallMaterial: !!this.#data.options.materials.outerWall.changed.pending,
|
|
270
|
+
options_innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed.pending,
|
|
271
|
+
options_outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed.pending,
|
|
272
272
|
};
|
|
273
273
|
const loadedDetail = {
|
|
274
|
-
container_model: !!this.#data.containers.model.changed
|
|
275
|
-
container_environment: !!this.#data.containers.environment.changed
|
|
276
|
-
container_materials: !!this.#data.containers.materials.changed
|
|
277
|
-
options_camera: !!this.#data.options.camera.changed
|
|
278
|
-
options_innerWallMaterial: !!this.#data.options.materials.innerWall.changed
|
|
279
|
-
options_outerWallMaterial: !!this.#data.options.materials.outerWall.changed
|
|
280
|
-
options_innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed
|
|
281
|
-
options_outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed
|
|
274
|
+
container_model: !!this.#data.containers.model.changed.success,
|
|
275
|
+
container_environment: !!this.#data.containers.environment.changed.success,
|
|
276
|
+
container_materials: !!this.#data.containers.materials.changed.success,
|
|
277
|
+
options_camera: !!this.#data.options.camera.changed.success,
|
|
278
|
+
options_innerWallMaterial: !!this.#data.options.materials.innerWall.changed.success,
|
|
279
|
+
options_outerWallMaterial: !!this.#data.options.materials.outerWall.changed.success,
|
|
280
|
+
options_innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed.success,
|
|
281
|
+
options_outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed.success,
|
|
282
282
|
};
|
|
283
283
|
|
|
284
284
|
const detail = {
|
|
@@ -315,16 +315,16 @@ class PrefViewer extends HTMLElement {
|
|
|
315
315
|
#setStatusOptionsLoaded() {
|
|
316
316
|
console.log("PrefViewer: #setStatusOptionsLoaded()");
|
|
317
317
|
const toLoadDetail = {
|
|
318
|
-
innerWallMaterial: !!this.#data.options.materials.innerWall.changed,
|
|
319
|
-
outerWallMaterial: !!this.#data.options.materials.outerWall.changed,
|
|
320
|
-
innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed,
|
|
321
|
-
outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed,
|
|
318
|
+
innerWallMaterial: !!this.#data.options.materials.innerWall.changed.pending,
|
|
319
|
+
outerWallMaterial: !!this.#data.options.materials.outerWall.changed.pending,
|
|
320
|
+
innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed.pending,
|
|
321
|
+
outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed.pending,
|
|
322
322
|
};
|
|
323
323
|
const loadedDetail = {
|
|
324
|
-
innerWallMaterial: !!this.#data.options.materials.innerWall.changed
|
|
325
|
-
outerWallMaterial: !!this.#data.options.materials.outerWall.changed
|
|
326
|
-
innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed
|
|
327
|
-
outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed
|
|
324
|
+
innerWallMaterial: !!this.#data.options.materials.innerWall.changed.success,
|
|
325
|
+
outerWallMaterial: !!this.#data.options.materials.outerWall.changed.success,
|
|
326
|
+
innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed.success,
|
|
327
|
+
outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed.success,
|
|
328
328
|
};
|
|
329
329
|
|
|
330
330
|
const detail = {
|
|
@@ -350,7 +350,13 @@ class PrefViewer extends HTMLElement {
|
|
|
350
350
|
}
|
|
351
351
|
const changed = options.camera !== this.#data.options.camera.value;
|
|
352
352
|
console.log("PrefViewer: #checkCameraChanged()", { incoming: options.camera, previous: this.#data.options.camera.value, changed });
|
|
353
|
-
this.#data.options.camera.changed =
|
|
353
|
+
this.#data.options.camera.changed = {
|
|
354
|
+
...this.#data.options.camera.changed,
|
|
355
|
+
pending: changed,
|
|
356
|
+
success: false,
|
|
357
|
+
oldValue: changed ? this.#data.options.camera.value : this.#data.options.camera.changed.oldValue,
|
|
358
|
+
oldLocked: changed ? this.#data.options.camera.locked : this.#data.options.camera.changed.oldLocked,
|
|
359
|
+
};
|
|
354
360
|
if (changed) this.#data.options.camera.value = options.camera;
|
|
355
361
|
|
|
356
362
|
return changed;
|
|
@@ -363,11 +369,19 @@ class PrefViewer extends HTMLElement {
|
|
|
363
369
|
let someChanged = false;
|
|
364
370
|
Object.keys(this.#data.options.materials).forEach((material) => {
|
|
365
371
|
const key = `${material}Material`;
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
372
|
+
const materialState = this.#data.options.materials[material];
|
|
373
|
+
const prev = materialState.value;
|
|
374
|
+
const incoming = options[key];
|
|
375
|
+
const materialChanged = !!incoming && incoming !== prev;
|
|
376
|
+
console.log("PrefViewer: #checkMaterialsChanged()", { key, incoming, previous: prev, materialChanged });
|
|
377
|
+
materialState.changed = {
|
|
378
|
+
...materialState.changed,
|
|
379
|
+
pending: materialChanged,
|
|
380
|
+
success: false,
|
|
381
|
+
oldValue: materialChanged ? prev : materialState.changed.oldValue,
|
|
382
|
+
};
|
|
383
|
+
materialState.value = materialChanged ? incoming : prev;
|
|
384
|
+
someChanged = someChanged || materialChanged;
|
|
371
385
|
});
|
|
372
386
|
return someChanged;
|
|
373
387
|
}
|
|
@@ -377,13 +391,18 @@ class PrefViewer extends HTMLElement {
|
|
|
377
391
|
container.timeStamp = container.changed.timeStamp;
|
|
378
392
|
container.size = container.changed.size;
|
|
379
393
|
container.changed.success = true;
|
|
394
|
+
container.changed.pending = false;
|
|
380
395
|
}
|
|
381
396
|
|
|
382
397
|
#resetChangedFlags() {
|
|
383
398
|
console.log("PrefViewer: #resetChangedFlags()");
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
399
|
+
const reset = (node) => {
|
|
400
|
+
node.changed.success = false;
|
|
401
|
+
node.changed.pending = false;
|
|
402
|
+
};
|
|
403
|
+
Object.values(this.#data.containers).forEach(reset);
|
|
404
|
+
Object.values(this.#data.options.materials).forEach(reset);
|
|
405
|
+
reset(this.#data.options.camera);
|
|
387
406
|
}
|
|
388
407
|
|
|
389
408
|
// Babylon.js
|
|
@@ -646,15 +665,15 @@ class PrefViewer extends HTMLElement {
|
|
|
646
665
|
return false;
|
|
647
666
|
}
|
|
648
667
|
|
|
649
|
-
const hadExplicitChange = !!optionMaterial.changed;
|
|
668
|
+
const hadExplicitChange = !!optionMaterial.changed.pending;
|
|
650
669
|
|
|
651
670
|
const containers = [];
|
|
652
671
|
if (this.#data.containers.model.assetContainer &&
|
|
653
|
-
(this.#data.containers.model.changed || this.#data.containers.materials.changed || optionMaterial.changed)) {
|
|
672
|
+
(this.#data.containers.model.changed.pending || this.#data.containers.materials.changed.pending || optionMaterial.changed.pending)) {
|
|
654
673
|
containers.push(this.#data.containers.model.assetContainer);
|
|
655
674
|
}
|
|
656
675
|
if (this.#data.containers.environment.assetContainer &&
|
|
657
|
-
(this.#data.containers.environment.changed || this.#data.containers.materials.changed || optionMaterial.changed)) {
|
|
676
|
+
(this.#data.containers.environment.changed.pending || this.#data.containers.materials.changed.pending || optionMaterial.changed.pending)) {
|
|
658
677
|
containers.push(this.#data.containers.environment.assetContainer);
|
|
659
678
|
}
|
|
660
679
|
if (containers.length === 0) {
|
|
@@ -677,11 +696,8 @@ class PrefViewer extends HTMLElement {
|
|
|
677
696
|
});
|
|
678
697
|
|
|
679
698
|
if (someSetted) {
|
|
680
|
-
// Asegura estructura si antes era `false`
|
|
681
|
-
if (!optionMaterial.changed) {
|
|
682
|
-
optionMaterial.changed = { oldValue: optionMaterial.value, success: false };
|
|
683
|
-
}
|
|
684
699
|
optionMaterial.changed.success = true;
|
|
700
|
+
optionMaterial.changed.pending = false;
|
|
685
701
|
} else if (hadExplicitChange) {
|
|
686
702
|
// Solo revertimos si el usuario pidió el cambio y falló
|
|
687
703
|
optionMaterial.value = optionMaterial.changed.oldValue;
|
|
@@ -711,11 +727,11 @@ class PrefViewer extends HTMLElement {
|
|
|
711
727
|
|
|
712
728
|
const camState = this.#data.options.camera;
|
|
713
729
|
|
|
714
|
-
if (!camState.value && !camState.changed && !this.#data.containers.model.changed && !this.#data.containers.environment.changed) {
|
|
730
|
+
if (!camState.value && !camState.changed.pending && !this.#data.containers.model.changed.pending && !this.#data.containers.environment.changed.pending) {
|
|
715
731
|
return false;
|
|
716
732
|
}
|
|
717
733
|
|
|
718
|
-
const hadExplicitChange = !!camState.changed;
|
|
734
|
+
const hadExplicitChange = !!camState.changed.pending;
|
|
719
735
|
|
|
720
736
|
let camera =
|
|
721
737
|
this.#data.containers.model.assetContainer?.cameras.find(c => c.name === camState.value) ||
|
|
@@ -730,20 +746,19 @@ class PrefViewer extends HTMLElement {
|
|
|
730
746
|
this.#data.containers.environment.assetContainer?.cameras.find(c => c.name === camState.changed.oldValue) ||
|
|
731
747
|
null;
|
|
732
748
|
|
|
733
|
-
// Asegura estructura para escribir success
|
|
734
|
-
if (!camState.changed) camState.changed = { oldValue: camState.value, oldLocked: camState.locked, success: false };
|
|
735
|
-
|
|
736
749
|
if (camera) {
|
|
737
750
|
camera.metadata = { locked: camState.changed.oldLocked };
|
|
738
751
|
camState.value = camState.changed.oldValue;
|
|
739
752
|
camState.locked = camState.changed.oldLocked;
|
|
740
753
|
camState.changed.success = false;
|
|
754
|
+
camState.changed.pending = false;
|
|
741
755
|
} else {
|
|
742
756
|
// Fallback a la cámara por defecto del componente
|
|
743
757
|
camera = this.#camera;
|
|
744
758
|
camState.value = null;
|
|
745
759
|
camState.locked = this.#camera.metadata.locked;
|
|
746
760
|
camState.changed.success = false;
|
|
761
|
+
camState.changed.pending = false;
|
|
747
762
|
}
|
|
748
763
|
} else {
|
|
749
764
|
// No hubo cambio explícito: usa fallback sin tocar changed
|
|
@@ -755,8 +770,8 @@ class PrefViewer extends HTMLElement {
|
|
|
755
770
|
camera.metadata = { locked: camState.locked };
|
|
756
771
|
// Marca success si hubo cambio explícito
|
|
757
772
|
if (hadExplicitChange) {
|
|
758
|
-
if (!camState.changed) camState.changed = { oldValue: camState.value, oldLocked: camState.locked, success: false };
|
|
759
773
|
camState.changed.success = true;
|
|
774
|
+
camState.changed.pending = false;
|
|
760
775
|
}
|
|
761
776
|
}
|
|
762
777
|
|
|
@@ -839,7 +854,13 @@ class PrefViewer extends HTMLElement {
|
|
|
839
854
|
console.log("PrefViewer: DB entry unchanged, skipping", container.name);
|
|
840
855
|
return false;
|
|
841
856
|
} else {
|
|
842
|
-
container.changed = {
|
|
857
|
+
container.changed = {
|
|
858
|
+
...container.changed,
|
|
859
|
+
pending: true,
|
|
860
|
+
success: false,
|
|
861
|
+
timeStamp: object.timeStamp,
|
|
862
|
+
size: object.size,
|
|
863
|
+
};
|
|
843
864
|
console.log("PrefViewer: DB entry changed", container.changed);
|
|
844
865
|
}
|
|
845
866
|
}
|
|
@@ -856,12 +877,18 @@ class PrefViewer extends HTMLElement {
|
|
|
856
877
|
file = new File([blob], `${container.name}${extension}`, {
|
|
857
878
|
type: blob.type,
|
|
858
879
|
});
|
|
859
|
-
if (!container.changed) {
|
|
880
|
+
if (!container.changed.pending) {
|
|
860
881
|
if (container.timeStamp === null && container.size === size) {
|
|
861
882
|
console.log("PrefViewer: same base64 size and null timestamp, skipping", container.name);
|
|
862
883
|
return false;
|
|
863
884
|
} else {
|
|
864
|
-
container.changed = {
|
|
885
|
+
container.changed = {
|
|
886
|
+
...container.changed,
|
|
887
|
+
pending: true,
|
|
888
|
+
success: false,
|
|
889
|
+
timeStamp: null,
|
|
890
|
+
size: size,
|
|
891
|
+
};
|
|
865
892
|
}
|
|
866
893
|
}
|
|
867
894
|
console.log("PrefViewer: prepared File from base64", { name: file.name, size: file.size, type: file.type });
|
|
@@ -873,7 +900,13 @@ class PrefViewer extends HTMLElement {
|
|
|
873
900
|
console.log("PrefViewer: remote file unchanged, skipping", container.name);
|
|
874
901
|
return false;
|
|
875
902
|
} else {
|
|
876
|
-
container.changed = {
|
|
903
|
+
container.changed = {
|
|
904
|
+
...container.changed,
|
|
905
|
+
pending: true,
|
|
906
|
+
success: false,
|
|
907
|
+
timeStamp: fileTimeStamp,
|
|
908
|
+
size: fileSize,
|
|
909
|
+
};
|
|
877
910
|
console.log("PrefViewer: remote file changed", container.changed);
|
|
878
911
|
}
|
|
879
912
|
}
|