@xh/hoist 72.0.0-SNAPSHOT.1736881018782 → 72.0.0-SNAPSHOT.1736893155432

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 CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## v72.0.0-SNAPSHOT - unreleased
4
4
 
5
+ ### ⚙️ Technical
6
+
7
+ * Added support for providing custom `PersistenceProvider` implementations to `PersistOptions`.
8
+
9
+
5
10
  ### ⚙️ Typescript API Adjustments
6
11
 
7
12
  * Improved signature of `HoistBase.markPersist`.
@@ -1,17 +1,24 @@
1
- import { DebounceSpec } from '../';
1
+ import { Class } from 'type-fest';
2
+ import { DebounceSpec, PersistenceProvider, PersistenceProviderConfig } from '../';
2
3
  import type { DashViewModel } from '@xh/hoist/desktop/cmp/dash';
3
4
  import type { ViewManagerModel } from '@xh/hoist/cmp/viewmanager';
5
+ /**
6
+ * Built-in Hoist PersistenceProviders.
7
+ */
8
+ export type PersistenceProviderType = 'pref' | 'localStorage' | 'sessionStorage' | 'dashView' | 'viewManager' | 'custom';
4
9
  export interface PersistOptions {
5
10
  /** Dot delimited path to store state. */
6
11
  path?: string;
7
12
  /** Debounce interval in ms, or a lodash debounce config. */
8
13
  debounce?: DebounceSpec;
9
14
  /**
10
- * Type of PersistenceProvider to create. If not provided, defaulted based
11
- * on the presence of `prefKey`, `localStorageKey`, `dashViewModel`, 'viewManagerModel',
12
- * `getData` and `setData`.
15
+ * Type of PersistenceProvider to create. Specify as one of the built-in string types,
16
+ * or a subclass of PersistenceProvider.
17
+ *
18
+ * If not provided, defaulted to one of the built-in string types based on the presence of
19
+ * `prefKey`, `localStorageKey`, `dashViewModel`, 'viewManagerModel', or `getData/setData`.
13
20
  */
14
- type?: 'pref' | 'localStorage' | 'sessionStorage' | 'dashView' | 'viewManager' | 'custom';
21
+ type?: PersistenceProviderType | Class<PersistenceProvider, [PersistenceProviderConfig]>;
15
22
  /** Predefined Hoist application Preference key used to store state. */
16
23
  prefKey?: string;
17
24
  /** Browser local storage key used to store state. */
@@ -1,12 +1,8 @@
1
1
  import { DebounceSpec, HoistBase, Persistable, PersistableState } from '../';
2
2
  import { PersistOptions } from './';
3
- export type PersistenceProviderConfig<S> = {
3
+ export type PersistenceProviderConfig<S = any> = {
4
4
  persistOptions: PersistOptions;
5
5
  target: Persistable<S>;
6
- owner: HoistBase;
7
- } | {
8
- persistOptions: PersistOptions;
9
- target: Persistable<S> & HoistBase;
10
6
  owner?: HoistBase;
11
7
  };
12
8
  /**
@@ -26,7 +22,7 @@ export type PersistenceProviderConfig<S> = {
26
22
  * - {@link ViewManagerProvider} - persists to saved views managed by {@link ViewManagerModel}.
27
23
  * - {@link CustomProvider} - API for app and components to provide their own storage mechanism.
28
24
  */
29
- export declare abstract class PersistenceProvider<S> {
25
+ export declare abstract class PersistenceProvider<S = any> {
30
26
  readonly path: string;
31
27
  readonly debounce: DebounceSpec;
32
28
  readonly owner: HoistBase;
@@ -59,4 +55,5 @@ export declare abstract class PersistenceProvider<S> {
59
55
  protected writeInternal(data: S): void;
60
56
  protected writeRaw(obj: Record<typeof this.path, S>): void;
61
57
  protected readRaw(): Record<typeof this.path, S>;
58
+ private static parseProviderClass;
62
59
  }
@@ -5,10 +5,22 @@
5
5
  * Copyright © 2025 Extremely Heavy Industries Inc.
6
6
  */
7
7
 
8
- import {DebounceSpec} from '../';
8
+ import {Class} from 'type-fest';
9
+ import {DebounceSpec, PersistenceProvider, PersistenceProviderConfig} from '../';
9
10
  import type {DashViewModel} from '@xh/hoist/desktop/cmp/dash'; // Import type only
10
11
  import type {ViewManagerModel} from '@xh/hoist/cmp/viewmanager'; // Import type only
11
12
 
13
+ /**
14
+ * Built-in Hoist PersistenceProviders.
15
+ */
16
+ export type PersistenceProviderType =
17
+ | 'pref'
18
+ | 'localStorage'
19
+ | 'sessionStorage'
20
+ | 'dashView'
21
+ | 'viewManager'
22
+ | 'custom';
23
+
12
24
  export interface PersistOptions {
13
25
  /** Dot delimited path to store state. */
14
26
  path?: string;
@@ -17,11 +29,13 @@ export interface PersistOptions {
17
29
  debounce?: DebounceSpec;
18
30
 
19
31
  /**
20
- * Type of PersistenceProvider to create. If not provided, defaulted based
21
- * on the presence of `prefKey`, `localStorageKey`, `dashViewModel`, 'viewManagerModel',
22
- * `getData` and `setData`.
32
+ * Type of PersistenceProvider to create. Specify as one of the built-in string types,
33
+ * or a subclass of PersistenceProvider.
34
+ *
35
+ * If not provided, defaulted to one of the built-in string types based on the presence of
36
+ * `prefKey`, `localStorageKey`, `dashViewModel`, 'viewManagerModel', or `getData/setData`.
23
37
  */
24
- type?: 'pref' | 'localStorage' | 'sessionStorage' | 'dashView' | 'viewManager' | 'custom';
38
+ type?: PersistenceProviderType | Class<PersistenceProvider, [PersistenceProviderConfig]>;
25
39
 
26
40
  /** Predefined Hoist application Preference key used to store state. */
27
41
  prefKey?: string;
@@ -12,33 +12,29 @@ import {
12
12
  get,
13
13
  isEmpty,
14
14
  isNumber,
15
+ isString,
15
16
  isUndefined,
16
17
  set,
17
18
  toPath
18
19
  } from 'lodash';
19
20
  import {IReactionDisposer, reaction} from 'mobx';
20
- import {DebounceSpec, HoistBase, Persistable, PersistableState, XH} from '../';
21
+ import {Class} from 'type-fest';
22
+ import {DebounceSpec, HoistBase, Persistable, PersistableState} from '../';
21
23
  import {
22
24
  CustomProvider,
23
25
  DashViewProvider,
24
26
  LocalStorageProvider,
25
- SessionStorageProvider,
26
27
  PersistOptions,
27
28
  PrefProvider,
29
+ SessionStorageProvider,
28
30
  ViewManagerProvider
29
31
  } from './';
30
32
 
31
- export type PersistenceProviderConfig<S> =
32
- | {
33
- persistOptions: PersistOptions;
34
- target: Persistable<S>;
35
- owner: HoistBase;
36
- }
37
- | {
38
- persistOptions: PersistOptions;
39
- target: Persistable<S> & HoistBase;
40
- owner?: HoistBase;
41
- };
33
+ export type PersistenceProviderConfig<S = any> = {
34
+ persistOptions: PersistOptions;
35
+ target: Persistable<S>;
36
+ owner?: HoistBase;
37
+ };
42
38
 
43
39
  /**
44
40
  * Abstract superclass for adaptor objects used by models and components to (re)store state to and
@@ -57,7 +53,7 @@ export type PersistenceProviderConfig<S> =
57
53
  * - {@link ViewManagerProvider} - persists to saved views managed by {@link ViewManagerModel}.
58
54
  * - {@link CustomProvider} - API for app and components to provide their own storage mechanism.
59
55
  */
60
- export abstract class PersistenceProvider<S> {
56
+ export abstract class PersistenceProvider<S = any> {
61
57
  readonly path: string;
62
58
  readonly debounce: DebounceSpec;
63
59
  readonly owner: HoistBase;
@@ -79,49 +75,14 @@ export abstract class PersistenceProvider<S> {
79
75
  * target without thrashing.
80
76
  */
81
77
  static create<S>(cfg: PersistenceProviderConfig<S>): PersistenceProvider<S> {
82
- cfg = {
83
- owner: cfg.target instanceof HoistBase ? cfg.target : cfg.owner,
84
- ...cfg
85
- };
86
- const {target, persistOptions} = cfg;
87
-
88
- let {type, ...rest} = persistOptions,
89
- ret: PersistenceProvider<S>;
90
-
78
+ let ret: PersistenceProvider<S>;
91
79
  try {
92
- if (!type) {
93
- if (rest.prefKey) type = 'pref';
94
- if (rest.localStorageKey) type = 'localStorage';
95
- if (rest.sessionStorageKey) type = 'sessionStorage';
96
- if (rest.dashViewModel) type = 'dashView';
97
- if (rest.viewManagerModel) type = 'viewManager';
98
- if (rest.getData || rest.setData) type = 'custom';
99
- }
100
-
101
- switch (type) {
102
- case 'pref':
103
- ret = new PrefProvider(cfg);
104
- break;
105
- case 'localStorage':
106
- ret = new LocalStorageProvider(cfg);
107
- break;
108
- case 'sessionStorage':
109
- ret = new SessionStorageProvider(cfg);
110
- break;
111
- case `dashView`:
112
- ret = new DashViewProvider(cfg);
113
- break;
114
- case `viewManager`:
115
- ret = new ViewManagerProvider(cfg);
116
- break;
117
- case 'custom':
118
- ret = new CustomProvider(cfg);
119
- break;
120
- default:
121
- throw XH.exception(`Unknown Persistence Provider for type: ${type}`);
122
- }
80
+ // default owner to target
81
+ cfg = {owner: cfg.target instanceof HoistBase ? cfg.target : cfg.owner, ...cfg};
123
82
 
124
- ret.bindToTarget(target);
83
+ const providerClass = this.parseProviderClass<S>(cfg.persistOptions);
84
+ ret = new providerClass(cfg);
85
+ ret.bindToTarget(cfg.target);
125
86
  return ret;
126
87
  } catch (e) {
127
88
  logError(e, cfg.owner);
@@ -211,7 +172,39 @@ export abstract class PersistenceProvider<S> {
211
172
  }
212
173
 
213
174
  protected writeRaw(obj: Record<typeof this.path, S>) {}
175
+
214
176
  protected readRaw(): Record<typeof this.path, S> {
215
177
  return null;
216
178
  }
179
+
180
+ private static parseProviderClass<S>(
181
+ opts: PersistOptions
182
+ ): Class<PersistenceProvider<S>, [PersistenceProviderConfig<S>]> {
183
+ // 1) Recognize shortcut form
184
+ const {type, ...rest} = opts;
185
+ if (!type) {
186
+ if (rest.prefKey) return PrefProvider;
187
+ if (rest.localStorageKey) return LocalStorageProvider;
188
+ if (rest.sessionStorageKey) return SessionStorageProvider;
189
+ if (rest.dashViewModel) return DashViewProvider;
190
+ if (rest.viewManagerModel) return ViewManagerProvider;
191
+ if (rest.getData || rest.setData) return CustomProvider;
192
+ }
193
+
194
+ // 2) Map any string to known Provider Class, or return raw class
195
+ const ret = isString(type)
196
+ ? {
197
+ pref: PrefProvider,
198
+ localStorage: LocalStorageProvider,
199
+ sessionStorage: SessionStorageProvider,
200
+ dashView: DashViewProvider,
201
+ viewManager: ViewManagerProvider,
202
+ custom: CustomProvider
203
+ }[type]
204
+ : type;
205
+
206
+ throwIf(!ret, `Unknown Persistence Provider: ${type}`);
207
+
208
+ return ret;
209
+ }
217
210
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xh/hoist",
3
- "version": "72.0.0-SNAPSHOT.1736881018782",
3
+ "version": "72.0.0-SNAPSHOT.1736893155432",
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",