@xh/hoist 74.0.0-SNAPSHOT.1748547679578 → 74.0.0-SNAPSHOT.1748629362620
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/CHANGELOG.md +12 -0
- package/build/types/cmp/viewmanager/ViewManagerModel.d.ts +20 -16
- package/build/types/core/persist/PersistOptions.d.ts +4 -0
- package/build/types/core/persist/PersistenceProvider.d.ts +3 -0
- package/cmp/grid/impl/InitPersist.ts +13 -3
- package/cmp/viewmanager/ViewManagerModel.ts +41 -28
- package/core/persist/PersistOptions.ts +5 -0
- package/core/persist/PersistenceProvider.ts +17 -3
- package/core/persist/provider/ViewManagerProvider.ts +2 -6
- package/desktop/cmp/dash/canvas/DashCanvasModel.ts +1 -0
- package/desktop/cmp/dash/container/DashContainerModel.ts +1 -0
- package/package.json +1 -1
- package/promise/Promise.ts +6 -4
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## 74.0.0-SNAPSHOT - unreleased
|
|
4
4
|
|
|
5
|
+
### 💥 Breaking Changes (upgrade difficulty: 🟢 LOW - minor change to ViewManagerModel)
|
|
6
|
+
|
|
7
|
+
* Removed `ViewManagerModel.settleTime`. Now set via individual `PersistOptions.settleTime` instead.
|
|
8
|
+
|
|
9
|
+
### 🎁 New Features
|
|
10
|
+
* Added `ViewManagerModel.preserveUnsavedChanges` flag to opt-out of that behaviour.
|
|
11
|
+
* Added `PersistOptions.settleTime` to configure time to wait for state to settle before persisting.
|
|
12
|
+
|
|
13
|
+
### 🐞 Bug Fixes
|
|
14
|
+
* Improved `ViewManagerModel.settleTime` by delegating to individual `PersistenceProviders`.
|
|
15
|
+
* Fixed bug where grid column state could become unintentionally dirty when columns were hidden.
|
|
16
|
+
|
|
5
17
|
## v73.0.1 - 2025-05-19
|
|
6
18
|
|
|
7
19
|
### 🐞 Bug Fixes
|
|
@@ -43,6 +43,11 @@ export interface ViewManagerConfig {
|
|
|
43
43
|
* True (default) to allow users to share their views with other users.
|
|
44
44
|
*/
|
|
45
45
|
enableSharing?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* True (default) to save pending state to SessionStorage so that it can be restored across
|
|
48
|
+
* browser refreshes. Unlike auto-save, this does not write to the database.
|
|
49
|
+
*/
|
|
50
|
+
preserveUnsavedChanges?: boolean;
|
|
46
51
|
/**
|
|
47
52
|
* Function to determine the initial view for a user, when no view has already been persisted.
|
|
48
53
|
* Will be passed a list of views available to the current user. Implementations where
|
|
@@ -52,13 +57,6 @@ export interface ViewManagerConfig {
|
|
|
52
57
|
* Must be set when enableDefault is false.
|
|
53
58
|
*/
|
|
54
59
|
initialViewSpec?: (views: ViewInfo[]) => ViewInfo;
|
|
55
|
-
/**
|
|
56
|
-
* Delay (in ms) to wait after state has been set on associated components before listening for
|
|
57
|
-
* further state changes. The long default wait 1000ms is intended to avoid a false positive
|
|
58
|
-
* dirty indicator when linking to complex components such as dashboards or grids that can
|
|
59
|
-
* report immediate changes to state due to internal processing or rendering.
|
|
60
|
-
*/
|
|
61
|
-
settleTime?: number;
|
|
62
60
|
/**
|
|
63
61
|
* True to allow the user to publish or edit the global views. Apps are expected to
|
|
64
62
|
* commonly set this based on user roles - e.g. `XH.getUser().hasRole('MANAGE_GRID_VIEWS')`.
|
|
@@ -132,8 +130,8 @@ export declare class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
132
130
|
readonly enableDefault: boolean;
|
|
133
131
|
readonly enableGlobal: boolean;
|
|
134
132
|
readonly enableSharing: boolean;
|
|
133
|
+
readonly preserveUnsavedChanges: boolean;
|
|
135
134
|
readonly manageGlobal: boolean;
|
|
136
|
-
readonly settleTime: number;
|
|
137
135
|
readonly initialViewSpec: (views: ViewInfo[]) => ViewInfo;
|
|
138
136
|
/** Current view. Will not include uncommitted changes */
|
|
139
137
|
view: View<T>;
|
|
@@ -161,16 +159,12 @@ export declare class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
161
159
|
/** Unsaved changes on the current view.*/
|
|
162
160
|
private pendingValue;
|
|
163
161
|
/**
|
|
164
|
-
* Array of {@link ViewManagerProvider} instances bound to this model.
|
|
165
|
-
*
|
|
166
|
-
* proactively push state to the target components when the model's selected `value` changes.
|
|
167
|
-
* @internal
|
|
162
|
+
* Array of {@link ViewManagerProvider} instances bound to this model. Used to proactively push
|
|
163
|
+
* state to the target components when the model's selected `value` changes.
|
|
168
164
|
*/
|
|
169
|
-
providers
|
|
165
|
+
private providers;
|
|
170
166
|
/** Data access for persisting views. */
|
|
171
167
|
private dataAccess;
|
|
172
|
-
/** Last time changes were pushed to linked persistence providers */
|
|
173
|
-
private lastPushed;
|
|
174
168
|
get isValueDirty(): boolean;
|
|
175
169
|
get isViewSavable(): boolean;
|
|
176
170
|
get isViewAutoSavable(): boolean;
|
|
@@ -207,8 +201,18 @@ export declare class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
207
201
|
/** Promote a view to global visibility/ownership status. */
|
|
208
202
|
makeViewGlobalAsync(view: ViewInfo): Promise<View<T>>;
|
|
209
203
|
deleteViewsAsync(toDelete: ViewInfo[]): Promise<void>;
|
|
204
|
+
/**
|
|
205
|
+
* Called by {@link ViewManagerProvider} to receive state changes from this model.
|
|
206
|
+
* @internal
|
|
207
|
+
*/
|
|
208
|
+
registerProvider(provider: ViewManagerProvider<any>): void;
|
|
209
|
+
/**
|
|
210
|
+
* Called by {@link ViewManagerProvider} to stop receiving state changes.
|
|
211
|
+
* @internal
|
|
212
|
+
*/
|
|
213
|
+
unregisterProvider(provider: ViewManagerProvider<any>): void;
|
|
210
214
|
private initAsync;
|
|
211
|
-
private
|
|
215
|
+
private unsavedChangesReaction;
|
|
212
216
|
private autoSaveReaction;
|
|
213
217
|
private stateReactions;
|
|
214
218
|
private loadViewAsync;
|
|
@@ -11,6 +11,10 @@ export interface PersistOptions {
|
|
|
11
11
|
path?: string;
|
|
12
12
|
/** Debounce interval in ms, or a lodash debounce config. */
|
|
13
13
|
debounce?: DebounceSpec;
|
|
14
|
+
/**
|
|
15
|
+
* Delay (in ms) to wait after state has been read before listening for further state changes.
|
|
16
|
+
*/
|
|
17
|
+
settleTime?: number;
|
|
14
18
|
/**
|
|
15
19
|
* Type of PersistenceProvider to create. Specify as one of the built-in string types,
|
|
16
20
|
* or a subclass of PersistenceProvider.
|
|
@@ -26,9 +26,12 @@ export declare abstract class PersistenceProvider<S = any> {
|
|
|
26
26
|
readonly path: string;
|
|
27
27
|
readonly debounce: DebounceSpec;
|
|
28
28
|
readonly owner: HoistBase;
|
|
29
|
+
readonly settleTime: number;
|
|
29
30
|
protected target: Persistable<S>;
|
|
30
31
|
protected defaultState: PersistableState<S>;
|
|
31
32
|
private disposer;
|
|
33
|
+
private lastReadState;
|
|
34
|
+
private lastReadTime;
|
|
32
35
|
/**
|
|
33
36
|
* Construct an instance of this class.
|
|
34
37
|
*
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* Copyright © 2025 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
7
|
import {PersistableState, PersistenceProvider} from '@xh/hoist/core';
|
|
8
|
-
import {isObject} from 'lodash';
|
|
8
|
+
import {isEqual, isObject} from 'lodash';
|
|
9
9
|
import {GridModel} from '../GridModel';
|
|
10
|
-
import {GridModelPersistOptions} from '../Types';
|
|
10
|
+
import {ColumnState, GridModelPersistOptions} from '../Types';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Initialize persistence for a {@link GridModel} by applying its `persistWith` config.
|
|
@@ -33,7 +33,8 @@ export function initPersist(
|
|
|
33
33
|
...persistWith
|
|
34
34
|
},
|
|
35
35
|
target: {
|
|
36
|
-
getPersistableState: () =>
|
|
36
|
+
getPersistableState: () =>
|
|
37
|
+
new PersistableColumnState(gridModel.persistableColumnState),
|
|
37
38
|
setPersistableState: ({value}) => gridModel.setColumnState(value)
|
|
38
39
|
},
|
|
39
40
|
owner: gridModel
|
|
@@ -75,3 +76,12 @@ export function initPersist(
|
|
|
75
76
|
});
|
|
76
77
|
}
|
|
77
78
|
}
|
|
79
|
+
|
|
80
|
+
class PersistableColumnState extends PersistableState<ColumnState[]> {
|
|
81
|
+
override equals(other: PersistableState<ColumnState[]>): boolean {
|
|
82
|
+
return isEqual(
|
|
83
|
+
this.value.filter(it => !it.hidden),
|
|
84
|
+
other.value.filter(it => !it.hidden)
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -19,7 +19,7 @@ import type {ViewManagerProvider, ReactionSpec} from '@xh/hoist/core';
|
|
|
19
19
|
import {genDisplayName} from '@xh/hoist/data';
|
|
20
20
|
import {fmtDateTime} from '@xh/hoist/format';
|
|
21
21
|
import {action, bindable, makeObservable, observable, comparer, runInAction} from '@xh/hoist/mobx';
|
|
22
|
-
import {
|
|
22
|
+
import {SECONDS} from '@xh/hoist/utils/datetime';
|
|
23
23
|
import {executeIfFunction, pluralize, throwIf} from '@xh/hoist/utils/js';
|
|
24
24
|
import {find, isEqual, isNil, isNull, isObject, isUndefined, lowerCase, uniqBy} from 'lodash';
|
|
25
25
|
import {ReactNode} from 'react';
|
|
@@ -74,6 +74,12 @@ export interface ViewManagerConfig {
|
|
|
74
74
|
*/
|
|
75
75
|
enableSharing?: boolean;
|
|
76
76
|
|
|
77
|
+
/**
|
|
78
|
+
* True (default) to save pending state to SessionStorage so that it can be restored across
|
|
79
|
+
* browser refreshes. Unlike auto-save, this does not write to the database.
|
|
80
|
+
*/
|
|
81
|
+
preserveUnsavedChanges?: boolean;
|
|
82
|
+
|
|
77
83
|
/**
|
|
78
84
|
* Function to determine the initial view for a user, when no view has already been persisted.
|
|
79
85
|
* Will be passed a list of views available to the current user. Implementations where
|
|
@@ -84,14 +90,6 @@ export interface ViewManagerConfig {
|
|
|
84
90
|
*/
|
|
85
91
|
initialViewSpec?: (views: ViewInfo[]) => ViewInfo;
|
|
86
92
|
|
|
87
|
-
/**
|
|
88
|
-
* Delay (in ms) to wait after state has been set on associated components before listening for
|
|
89
|
-
* further state changes. The long default wait 1000ms is intended to avoid a false positive
|
|
90
|
-
* dirty indicator when linking to complex components such as dashboards or grids that can
|
|
91
|
-
* report immediate changes to state due to internal processing or rendering.
|
|
92
|
-
*/
|
|
93
|
-
settleTime?: number;
|
|
94
|
-
|
|
95
93
|
/**
|
|
96
94
|
* True to allow the user to publish or edit the global views. Apps are expected to
|
|
97
95
|
* commonly set this based on user roles - e.g. `XH.getUser().hasRole('MANAGE_GRID_VIEWS')`.
|
|
@@ -176,8 +174,8 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
176
174
|
readonly enableDefault: boolean;
|
|
177
175
|
readonly enableGlobal: boolean;
|
|
178
176
|
readonly enableSharing: boolean;
|
|
177
|
+
readonly preserveUnsavedChanges: boolean;
|
|
179
178
|
readonly manageGlobal: boolean;
|
|
180
|
-
readonly settleTime: number;
|
|
181
179
|
readonly initialViewSpec: (views: ViewInfo[]) => ViewInfo;
|
|
182
180
|
|
|
183
181
|
/** Current view. Will not include uncommitted changes */
|
|
@@ -216,19 +214,14 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
216
214
|
private pendingValue: PendingValue<T> = null;
|
|
217
215
|
|
|
218
216
|
/**
|
|
219
|
-
* Array of {@link ViewManagerProvider} instances bound to this model.
|
|
220
|
-
*
|
|
221
|
-
* proactively push state to the target components when the model's selected `value` changes.
|
|
222
|
-
* @internal
|
|
217
|
+
* Array of {@link ViewManagerProvider} instances bound to this model. Used to proactively push
|
|
218
|
+
* state to the target components when the model's selected `value` changes.
|
|
223
219
|
*/
|
|
224
|
-
providers: ViewManagerProvider<any>[] = [];
|
|
220
|
+
private providers: ViewManagerProvider<any>[] = [];
|
|
225
221
|
|
|
226
222
|
/** Data access for persisting views. */
|
|
227
223
|
private dataAccess: DataAccess<T>;
|
|
228
224
|
|
|
229
|
-
/** Last time changes were pushed to linked persistence providers */
|
|
230
|
-
private lastPushed: number = null;
|
|
231
|
-
|
|
232
225
|
//---------------
|
|
233
226
|
// Getters
|
|
234
227
|
//---------------
|
|
@@ -296,7 +289,7 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
296
289
|
enableDefault = true,
|
|
297
290
|
enableGlobal = true,
|
|
298
291
|
enableSharing = true,
|
|
299
|
-
|
|
292
|
+
preserveUnsavedChanges = true,
|
|
300
293
|
initialViewSpec = null
|
|
301
294
|
}: ViewManagerConfig) {
|
|
302
295
|
super();
|
|
@@ -317,7 +310,7 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
317
310
|
this.enableGlobal = enableGlobal;
|
|
318
311
|
this.enableSharing = enableSharing;
|
|
319
312
|
this.enableAutoSave = enableAutoSave;
|
|
320
|
-
this.
|
|
313
|
+
this.preserveUnsavedChanges = preserveUnsavedChanges;
|
|
321
314
|
this.initialViewSpec = initialViewSpec;
|
|
322
315
|
|
|
323
316
|
this.selectTask = TaskObserver.trackLast({
|
|
@@ -421,10 +414,7 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
421
414
|
|
|
422
415
|
@action
|
|
423
416
|
setValue(value: Partial<T>) {
|
|
424
|
-
const {view, pendingValue
|
|
425
|
-
if (!pendingValue && settleTime && !olderThan(lastPushed, settleTime)) {
|
|
426
|
-
return;
|
|
427
|
-
}
|
|
417
|
+
const {view, pendingValue} = this;
|
|
428
418
|
|
|
429
419
|
value = this.cleanState(value);
|
|
430
420
|
if (!isEqual(value, view.value)) {
|
|
@@ -500,6 +490,25 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
500
490
|
if (exception) throw exception;
|
|
501
491
|
}
|
|
502
492
|
|
|
493
|
+
//------------------
|
|
494
|
+
// Internal
|
|
495
|
+
//------------------
|
|
496
|
+
/**
|
|
497
|
+
* Called by {@link ViewManagerProvider} to receive state changes from this model.
|
|
498
|
+
* @internal
|
|
499
|
+
*/
|
|
500
|
+
registerProvider(provider: ViewManagerProvider<any>) {
|
|
501
|
+
this.providers.push(provider);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Called by {@link ViewManagerProvider} to stop receiving state changes.
|
|
506
|
+
* @internal
|
|
507
|
+
*/
|
|
508
|
+
unregisterProvider(provider: ViewManagerProvider<any>) {
|
|
509
|
+
this.providers = this.providers.filter(it => it !== provider);
|
|
510
|
+
}
|
|
511
|
+
|
|
503
512
|
//------------------
|
|
504
513
|
// Implementation
|
|
505
514
|
//------------------
|
|
@@ -515,7 +524,9 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
515
524
|
this.views = views;
|
|
516
525
|
this.userPinned = state.userPinned;
|
|
517
526
|
this.autoSave = state.autoSave;
|
|
518
|
-
this.
|
|
527
|
+
if (this.preserveUnsavedChanges) {
|
|
528
|
+
this.pendingValue = XH.sessionStorageService.get(pendingValueStorageKey);
|
|
529
|
+
}
|
|
519
530
|
});
|
|
520
531
|
|
|
521
532
|
// 2) Initialize/choose initial view. Null is ok, and will yield default.
|
|
@@ -537,13 +548,13 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
537
548
|
}
|
|
538
549
|
|
|
539
550
|
this.addReaction(
|
|
540
|
-
this.
|
|
551
|
+
this.preserveUnsavedChanges ? this.unsavedChangesReaction() : null,
|
|
541
552
|
this.autoSaveReaction(),
|
|
542
553
|
...this.stateReactions(initialState)
|
|
543
554
|
);
|
|
544
555
|
}
|
|
545
556
|
|
|
546
|
-
private
|
|
557
|
+
private unsavedChangesReaction(): ReactionSpec {
|
|
547
558
|
return {
|
|
548
559
|
track: () => this.pendingValue,
|
|
549
560
|
run: v => XH.sessionStorageService.set(this.pendingValueStorageKey, v)
|
|
@@ -588,7 +599,6 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
588
599
|
.thenAction(latest => {
|
|
589
600
|
this.setAsView(latest, pendingValue?.token == token ? pendingValue : null);
|
|
590
601
|
this.providers.forEach(it => it.pushStateToTarget());
|
|
591
|
-
this.lastPushed = Date.now();
|
|
592
602
|
})
|
|
593
603
|
.linkTo(this.selectTask);
|
|
594
604
|
}
|
|
@@ -622,6 +632,9 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
622
632
|
if (!view.isDefault) {
|
|
623
633
|
this.views = uniqBy([view.info, ...this.views], 'token');
|
|
624
634
|
}
|
|
635
|
+
|
|
636
|
+
// Ensure providers have a clean reference of the current view state.
|
|
637
|
+
this.providers.forEach(it => it.read());
|
|
625
638
|
}
|
|
626
639
|
|
|
627
640
|
private handleException(e, opts: ExceptionHandlerOptions = {}) {
|
|
@@ -28,6 +28,11 @@ export interface PersistOptions {
|
|
|
28
28
|
/** Debounce interval in ms, or a lodash debounce config. */
|
|
29
29
|
debounce?: DebounceSpec;
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Delay (in ms) to wait after state has been read before listening for further state changes.
|
|
33
|
+
*/
|
|
34
|
+
settleTime?: number;
|
|
35
|
+
|
|
31
36
|
/**
|
|
32
37
|
* Type of PersistenceProvider to create. Specify as one of the built-in string types,
|
|
33
38
|
* or a subclass of PersistenceProvider.
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Copyright © 2025 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import {olderThan} from '@xh/hoist/utils/datetime';
|
|
8
9
|
import {logDebug, logError, throwIf} from '@xh/hoist/utils/js';
|
|
9
10
|
import {
|
|
10
11
|
cloneDeep,
|
|
@@ -59,11 +60,14 @@ export abstract class PersistenceProvider<S = any> {
|
|
|
59
60
|
readonly path: string;
|
|
60
61
|
readonly debounce: DebounceSpec;
|
|
61
62
|
readonly owner: HoistBase;
|
|
63
|
+
readonly settleTime: number;
|
|
62
64
|
|
|
63
65
|
protected target: Persistable<S>;
|
|
64
66
|
protected defaultState: PersistableState<S>;
|
|
65
67
|
|
|
66
68
|
private disposer: IReactionDisposer;
|
|
69
|
+
private lastReadState: PersistableState<S>;
|
|
70
|
+
private lastReadTime: number;
|
|
67
71
|
|
|
68
72
|
/**
|
|
69
73
|
* Construct an instance of this class.
|
|
@@ -126,7 +130,10 @@ export abstract class PersistenceProvider<S = any> {
|
|
|
126
130
|
read(): PersistableState<S> {
|
|
127
131
|
const state = get(this.readRaw(), this.path);
|
|
128
132
|
logDebug(['Reading state', state], this.owner);
|
|
129
|
-
|
|
133
|
+
const ret = !isUndefined(state) ? new PersistableState(state) : null;
|
|
134
|
+
this.lastReadState = ret;
|
|
135
|
+
this.lastReadTime = Date.now();
|
|
136
|
+
return ret;
|
|
130
137
|
}
|
|
131
138
|
|
|
132
139
|
/** Persist JSON-serializable state to this provider's path. */
|
|
@@ -161,11 +168,12 @@ export abstract class PersistenceProvider<S = any> {
|
|
|
161
168
|
const {owner, persistOptions} = cfg;
|
|
162
169
|
this.owner = owner;
|
|
163
170
|
|
|
164
|
-
const {path, debounce = 250} = persistOptions;
|
|
171
|
+
const {path, debounce = 250, settleTime} = persistOptions;
|
|
165
172
|
throwIf(!path, 'Path not specified in PersistenceProvider.');
|
|
166
173
|
|
|
167
174
|
this.path = path;
|
|
168
175
|
this.debounce = debounce;
|
|
176
|
+
this.settleTime = settleTime;
|
|
169
177
|
this.owner.markManaged(this);
|
|
170
178
|
|
|
171
179
|
if (debounce) {
|
|
@@ -187,8 +195,14 @@ export abstract class PersistenceProvider<S = any> {
|
|
|
187
195
|
this.disposer = reaction(
|
|
188
196
|
() => this.target.getPersistableState(),
|
|
189
197
|
state => {
|
|
190
|
-
if (
|
|
198
|
+
if (this.settleTime && !olderThan(this.lastReadTime, this.settleTime)) {
|
|
199
|
+
return;
|
|
200
|
+
} else if (state.equals(this.defaultState)) {
|
|
191
201
|
this.clear();
|
|
202
|
+
} else if (this.lastReadState && state.equals(this.lastReadState)) {
|
|
203
|
+
// If the last read state is equal to the current state, use the last read state
|
|
204
|
+
// to avoid appearing "dirty"
|
|
205
|
+
this.write(this.lastReadState.value);
|
|
192
206
|
} else {
|
|
193
207
|
this.write(state.value);
|
|
194
208
|
}
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import {throwIf} from '@xh/hoist/utils/js';
|
|
9
|
-
import {pull} from 'lodash';
|
|
10
9
|
import {PersistenceProvider, PersistenceProviderConfig} from '../PersistenceProvider';
|
|
11
10
|
import type {ViewManagerModel} from '@xh/hoist/cmp/viewmanager/ViewManagerModel';
|
|
12
11
|
|
|
@@ -18,7 +17,7 @@ export class ViewManagerProvider<S> extends PersistenceProvider<S> {
|
|
|
18
17
|
const {viewManagerModel} = cfg.persistOptions;
|
|
19
18
|
throwIf(!viewManagerModel, `ViewManagerProvider requires a 'viewManagerModel'.`);
|
|
20
19
|
this.viewManagerModel = viewManagerModel;
|
|
21
|
-
viewManagerModel.
|
|
20
|
+
viewManagerModel.registerProvider(this);
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
pushStateToTarget() {
|
|
@@ -38,10 +37,7 @@ export class ViewManagerProvider<S> extends PersistenceProvider<S> {
|
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
override destroy() {
|
|
41
|
-
|
|
42
|
-
pull(this.viewManagerModel.providers, this);
|
|
43
|
-
}
|
|
44
|
-
|
|
40
|
+
this.viewManagerModel?.unregisterProvider(this);
|
|
45
41
|
super.destroy();
|
|
46
42
|
}
|
|
47
43
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xh/hoist",
|
|
3
|
-
"version": "74.0.0-SNAPSHOT.
|
|
3
|
+
"version": "74.0.0-SNAPSHOT.1748629362620",
|
|
4
4
|
"description": "Hoist add-on for building and deploying React Applications.",
|
|
5
5
|
"repository": "github:xh/hoist-react",
|
|
6
6
|
"homepage": "https://xh.io",
|
package/promise/Promise.ts
CHANGED
|
@@ -202,7 +202,9 @@ const enhancePromise = promisePrototype => {
|
|
|
202
202
|
if (!options) return this;
|
|
203
203
|
|
|
204
204
|
const startTime = Date.now(),
|
|
205
|
-
doTrack = (
|
|
205
|
+
doTrack = (exception: unknown = null) => {
|
|
206
|
+
if (exception && exception['isRoutine']) return;
|
|
207
|
+
|
|
206
208
|
const endTime = Date.now(),
|
|
207
209
|
opts: TrackOptions = isString(options) ? {message: options} : {...options};
|
|
208
210
|
opts.timestamp = startTime;
|
|
@@ -220,18 +222,18 @@ const enhancePromise = promisePrototype => {
|
|
|
220
222
|
) {
|
|
221
223
|
opts.elapsed = null;
|
|
222
224
|
}
|
|
223
|
-
if (
|
|
225
|
+
if (exception) opts.severity = 'ERROR';
|
|
224
226
|
|
|
225
227
|
XH.track(opts);
|
|
226
228
|
};
|
|
227
229
|
|
|
228
230
|
return this.then(
|
|
229
231
|
(v: T) => {
|
|
230
|
-
doTrack(
|
|
232
|
+
doTrack();
|
|
231
233
|
return v;
|
|
232
234
|
},
|
|
233
235
|
(t: unknown) => {
|
|
234
|
-
doTrack(
|
|
236
|
+
doTrack(t);
|
|
235
237
|
throw t;
|
|
236
238
|
}
|
|
237
239
|
);
|