@push.rocks/smartstate 2.0.31 → 2.1.0
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/dist_ts/00_commitinfo_data.js +3 -3
- package/dist_ts/index.d.ts +2 -0
- package/dist_ts/index.js +3 -1
- package/dist_ts/smartstate.classes.computed.d.ts +7 -0
- package/dist_ts/smartstate.classes.computed.js +10 -0
- package/dist_ts/smartstate.classes.smartstate.d.ts +19 -10
- package/dist_ts/smartstate.classes.smartstate.js +44 -17
- package/dist_ts/smartstate.classes.statepart.d.ts +26 -9
- package/dist_ts/smartstate.classes.statepart.js +120 -24
- package/dist_ts/smartstate.contextprovider.d.ts +16 -0
- package/dist_ts/smartstate.contextprovider.js +44 -0
- package/npmextra.json +8 -2
- package/package.json +9 -4
- package/readme.hints.md +47 -30
- package/readme.md +218 -213
- package/ts/00_commitinfo_data.ts +2 -2
- package/ts/index.ts +2 -0
- package/ts/smartstate.classes.computed.ts +16 -0
- package/ts/smartstate.classes.smartstate.ts +51 -17
- package/ts/smartstate.classes.statepart.ts +140 -23
- package/ts/smartstate.contextprovider.ts +61 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartstate',
|
|
6
|
-
version: '2.0
|
|
7
|
-
description: 'A
|
|
6
|
+
version: '2.1.0',
|
|
7
|
+
description: 'A TypeScript-first reactive state management library with middleware, computed state, batching, persistence, and Web Component Context Protocol support.'
|
|
8
8
|
};
|
|
9
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx3QkFBd0I7SUFDOUIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLDBKQUEwSjtDQUN4SyxDQUFBIn0=
|
package/dist_ts/index.d.ts
CHANGED
package/dist_ts/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export * from './smartstate.classes.smartstate.js';
|
|
2
2
|
export * from './smartstate.classes.statepart.js';
|
|
3
3
|
export * from './smartstate.classes.stateaction.js';
|
|
4
|
-
|
|
4
|
+
export * from './smartstate.classes.computed.js';
|
|
5
|
+
export * from './smartstate.contextprovider.js';
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLG9DQUFvQyxDQUFDO0FBQ25ELGNBQWMsbUNBQW1DLENBQUM7QUFDbEQsY0FBYyxxQ0FBcUMsQ0FBQztBQUNwRCxjQUFjLGtDQUFrQyxDQUFDO0FBQ2pELGNBQWMsaUNBQWlDLENBQUMifQ==
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as plugins from './smartstate.plugins.js';
|
|
2
|
+
import type { StatePart } from './smartstate.classes.statepart.js';
|
|
3
|
+
/**
|
|
4
|
+
* creates a computed observable derived from multiple state parts.
|
|
5
|
+
* the observable is lazy — it only subscribes to sources when subscribed to.
|
|
6
|
+
*/
|
|
7
|
+
export declare function computed<TResult>(sources: StatePart<any, any>[], computeFn: (...states: any[]) => TResult): plugins.smartrx.rxjs.Observable<TResult>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as plugins from './smartstate.plugins.js';
|
|
2
|
+
import { combineLatest, map } from 'rxjs';
|
|
3
|
+
/**
|
|
4
|
+
* creates a computed observable derived from multiple state parts.
|
|
5
|
+
* the observable is lazy — it only subscribes to sources when subscribed to.
|
|
6
|
+
*/
|
|
7
|
+
export function computed(sources, computeFn) {
|
|
8
|
+
return combineLatest(sources.map((sp) => sp.select())).pipe(map((states) => computeFn(...states)));
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzdGF0ZS5jbGFzc2VzLmNvbXB1dGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRzdGF0ZS5jbGFzc2VzLmNvbXB1dGVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0seUJBQXlCLENBQUM7QUFDbkQsT0FBTyxFQUFFLGFBQWEsRUFBRSxHQUFHLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFHMUM7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLFFBQVEsQ0FDdEIsT0FBOEIsRUFDOUIsU0FBd0M7SUFFeEMsT0FBTyxhQUFhLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQ3pELEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FDTSxDQUFDO0FBQ2hELENBQUMifQ==
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as plugins from './smartstate.plugins.js';
|
|
1
2
|
import { StatePart } from './smartstate.classes.statepart.js';
|
|
2
3
|
export type TInitMode = 'soft' | 'mandatory' | 'force' | 'persistent';
|
|
3
4
|
/**
|
|
@@ -8,23 +9,31 @@ export declare class Smartstate<StatePartNameType extends string> {
|
|
|
8
9
|
[key in StatePartNameType]?: StatePart<StatePartNameType, any>;
|
|
9
10
|
};
|
|
10
11
|
private pendingStatePartCreation;
|
|
12
|
+
private batchDepth;
|
|
13
|
+
private pendingNotifications;
|
|
11
14
|
constructor();
|
|
15
|
+
/**
|
|
16
|
+
* whether state changes are currently being batched
|
|
17
|
+
*/
|
|
18
|
+
get isBatching(): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* registers a state part for deferred notification during a batch
|
|
21
|
+
*/
|
|
22
|
+
registerPendingNotification(statePart: StatePart<any, any>): void;
|
|
23
|
+
/**
|
|
24
|
+
* batches multiple state updates so subscribers are only notified once all updates complete
|
|
25
|
+
*/
|
|
26
|
+
batch(updateFn: () => Promise<void> | void): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* creates a computed observable derived from multiple state parts
|
|
29
|
+
*/
|
|
30
|
+
computed<TResult>(sources: StatePart<StatePartNameType, any>[], computeFn: (...states: any[]) => TResult): plugins.smartrx.rxjs.Observable<TResult>;
|
|
12
31
|
/**
|
|
13
32
|
* Allows getting and initializing a new statepart
|
|
14
|
-
* initMode === 'soft' (default) - returns existing statepart if exists, creates new if not
|
|
15
|
-
* initMode === 'mandatory' - requires statepart to not exist, fails if it does
|
|
16
|
-
* initMode === 'force' - always creates new statepart, overwriting any existing
|
|
17
|
-
* initMode === 'persistent' - like 'soft' but with webstore persistence
|
|
18
|
-
* @param statePartNameArg
|
|
19
|
-
* @param initialArg
|
|
20
|
-
* @param initMode
|
|
21
33
|
*/
|
|
22
34
|
getStatePart<PayloadType>(statePartNameArg: StatePartNameType, initialArg?: PayloadType, initMode?: TInitMode): Promise<StatePart<StatePartNameType, PayloadType>>;
|
|
23
35
|
/**
|
|
24
36
|
* Creates a statepart
|
|
25
|
-
* @param statePartName
|
|
26
|
-
* @param initialPayloadArg
|
|
27
|
-
* @param initMode
|
|
28
37
|
*/
|
|
29
38
|
private createStatePart;
|
|
30
39
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as plugins from './smartstate.plugins.js';
|
|
2
2
|
import { StatePart } from './smartstate.classes.statepart.js';
|
|
3
|
+
import { computed } from './smartstate.classes.computed.js';
|
|
3
4
|
/**
|
|
4
5
|
* Smartstate takes care of providing state
|
|
5
6
|
*/
|
|
@@ -7,16 +8,49 @@ export class Smartstate {
|
|
|
7
8
|
constructor() {
|
|
8
9
|
this.statePartMap = {};
|
|
9
10
|
this.pendingStatePartCreation = new Map();
|
|
11
|
+
// Batch support
|
|
12
|
+
this.batchDepth = 0;
|
|
13
|
+
this.pendingNotifications = new Set();
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* whether state changes are currently being batched
|
|
17
|
+
*/
|
|
18
|
+
get isBatching() {
|
|
19
|
+
return this.batchDepth > 0;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* registers a state part for deferred notification during a batch
|
|
23
|
+
*/
|
|
24
|
+
registerPendingNotification(statePart) {
|
|
25
|
+
this.pendingNotifications.add(statePart);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* batches multiple state updates so subscribers are only notified once all updates complete
|
|
29
|
+
*/
|
|
30
|
+
async batch(updateFn) {
|
|
31
|
+
this.batchDepth++;
|
|
32
|
+
try {
|
|
33
|
+
await updateFn();
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
this.batchDepth--;
|
|
37
|
+
if (this.batchDepth === 0) {
|
|
38
|
+
const pending = [...this.pendingNotifications];
|
|
39
|
+
this.pendingNotifications.clear();
|
|
40
|
+
for (const sp of pending) {
|
|
41
|
+
await sp.notifyChange();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* creates a computed observable derived from multiple state parts
|
|
48
|
+
*/
|
|
49
|
+
computed(sources, computeFn) {
|
|
50
|
+
return computed(sources, computeFn);
|
|
10
51
|
}
|
|
11
52
|
/**
|
|
12
53
|
* Allows getting and initializing a new statepart
|
|
13
|
-
* initMode === 'soft' (default) - returns existing statepart if exists, creates new if not
|
|
14
|
-
* initMode === 'mandatory' - requires statepart to not exist, fails if it does
|
|
15
|
-
* initMode === 'force' - always creates new statepart, overwriting any existing
|
|
16
|
-
* initMode === 'persistent' - like 'soft' but with webstore persistence
|
|
17
|
-
* @param statePartNameArg
|
|
18
|
-
* @param initialArg
|
|
19
|
-
* @param initMode
|
|
20
54
|
*/
|
|
21
55
|
async getStatePart(statePartNameArg, initialArg, initMode = 'soft') {
|
|
22
56
|
// Return pending creation if one exists to prevent duplicate state parts
|
|
@@ -30,17 +64,14 @@ export class Smartstate {
|
|
|
30
64
|
case 'mandatory':
|
|
31
65
|
throw new Error(`State part '${statePartNameArg}' already exists, but initMode is 'mandatory'`);
|
|
32
66
|
case 'force':
|
|
33
|
-
|
|
34
|
-
break; // Fall through to creation
|
|
67
|
+
break;
|
|
35
68
|
case 'soft':
|
|
36
69
|
case 'persistent':
|
|
37
70
|
default:
|
|
38
|
-
// Return existing state part
|
|
39
71
|
return existingStatePart;
|
|
40
72
|
}
|
|
41
73
|
}
|
|
42
74
|
else {
|
|
43
|
-
// State part doesn't exist
|
|
44
75
|
if (!initialArg) {
|
|
45
76
|
throw new Error(`State part '${statePartNameArg}' does not exist and no initial state provided`);
|
|
46
77
|
}
|
|
@@ -57,9 +88,6 @@ export class Smartstate {
|
|
|
57
88
|
}
|
|
58
89
|
/**
|
|
59
90
|
* Creates a statepart
|
|
60
|
-
* @param statePartName
|
|
61
|
-
* @param initialPayloadArg
|
|
62
|
-
* @param initMode
|
|
63
91
|
*/
|
|
64
92
|
async createStatePart(statePartName, initialPayloadArg, initMode = 'soft') {
|
|
65
93
|
const newState = new StatePart(statePartName, initMode === 'persistent'
|
|
@@ -68,21 +96,20 @@ export class Smartstate {
|
|
|
68
96
|
storeName: statePartName,
|
|
69
97
|
}
|
|
70
98
|
: null);
|
|
99
|
+
newState.smartstateRef = this;
|
|
71
100
|
await newState.init();
|
|
72
101
|
const currentState = newState.getState();
|
|
73
102
|
if (initMode === 'persistent' && currentState !== undefined) {
|
|
74
|
-
// Persisted state exists - merge with defaults, persisted values take precedence
|
|
75
103
|
await newState.setState({
|
|
76
104
|
...initialPayloadArg,
|
|
77
105
|
...currentState,
|
|
78
106
|
});
|
|
79
107
|
}
|
|
80
108
|
else {
|
|
81
|
-
// No persisted state or non-persistent mode
|
|
82
109
|
await newState.setState(initialPayloadArg);
|
|
83
110
|
}
|
|
84
111
|
this.statePartMap[statePartName] = newState;
|
|
85
112
|
return newState;
|
|
86
113
|
}
|
|
87
114
|
}
|
|
88
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
115
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzdGF0ZS5jbGFzc2VzLnNtYXJ0c3RhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydHN0YXRlLmNsYXNzZXMuc21hcnRzdGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLHlCQUF5QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUM5RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFJNUQ7O0dBRUc7QUFDSCxNQUFNLE9BQU8sVUFBVTtJQVNyQjtRQVJPLGlCQUFZLEdBQXVFLEVBQUUsQ0FBQztRQUVyRiw2QkFBd0IsR0FBNEQsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUV0RyxnQkFBZ0I7UUFDUixlQUFVLEdBQUcsQ0FBQyxDQUFDO1FBQ2YseUJBQW9CLEdBQUcsSUFBSSxHQUFHLEVBQXVCLENBQUM7SUFFL0MsQ0FBQztJQUVoQjs7T0FFRztJQUNILElBQVcsVUFBVTtRQUNuQixPQUFPLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFFRDs7T0FFRztJQUNJLDJCQUEyQixDQUFDLFNBQThCO1FBQy9ELElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLEtBQUssQ0FBQyxRQUFvQztRQUNyRCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDbEIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxRQUFRLEVBQUUsQ0FBQztRQUNuQixDQUFDO2dCQUFTLENBQUM7WUFDVCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDbEIsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUMxQixNQUFNLE9BQU8sR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixD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
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import * as plugins from './smartstate.plugins.js';
|
|
2
2
|
import { StateAction, type IActionDef } from './smartstate.classes.stateaction.js';
|
|
3
|
+
import type { Smartstate } from './smartstate.classes.smartstate.js';
|
|
4
|
+
export type TMiddleware<TPayload> = (newState: TPayload, oldState: TPayload | undefined) => TPayload | Promise<TPayload>;
|
|
3
5
|
export declare class StatePart<TStatePartName, TStatePayload> {
|
|
4
6
|
name: TStatePartName;
|
|
5
7
|
state: plugins.smartrx.rxjs.Subject<TStatePayload>;
|
|
6
8
|
stateStore: TStatePayload | undefined;
|
|
9
|
+
smartstateRef?: Smartstate<any>;
|
|
7
10
|
private cumulativeDeferred;
|
|
8
11
|
private pendingCumulativeNotification;
|
|
12
|
+
private pendingBatchNotification;
|
|
9
13
|
private webStoreOptions;
|
|
10
14
|
private webStore;
|
|
15
|
+
private middlewares;
|
|
16
|
+
private selectorCache;
|
|
17
|
+
private defaultSelectObservable;
|
|
11
18
|
constructor(nameArg: TStatePartName, webStoreOptionsArg?: plugins.webstore.IWebStoreOptions);
|
|
12
19
|
/**
|
|
13
20
|
* initializes the webstore
|
|
@@ -17,14 +24,18 @@ export declare class StatePart<TStatePartName, TStatePayload> {
|
|
|
17
24
|
* gets the state from the state store
|
|
18
25
|
*/
|
|
19
26
|
getState(): TStatePayload | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* adds a middleware that intercepts setState calls.
|
|
29
|
+
* middleware can transform the state or throw to reject it.
|
|
30
|
+
* returns a removal function.
|
|
31
|
+
*/
|
|
32
|
+
addMiddleware(middleware: TMiddleware<TStatePayload>): () => void;
|
|
20
33
|
/**
|
|
21
34
|
* sets the stateStore to the new state
|
|
22
|
-
* @param newStateArg
|
|
23
35
|
*/
|
|
24
36
|
setState(newStateArg: TStatePayload): Promise<TStatePayload>;
|
|
25
37
|
/**
|
|
26
38
|
* Validates state structure - can be overridden for custom validation
|
|
27
|
-
* @param stateArg
|
|
28
39
|
*/
|
|
29
40
|
protected validateState(stateArg: any): stateArg is TStatePayload;
|
|
30
41
|
/**
|
|
@@ -33,13 +44,17 @@ export declare class StatePart<TStatePartName, TStatePayload> {
|
|
|
33
44
|
notifyChange(): Promise<void>;
|
|
34
45
|
private lastStateNotificationPayloadHash;
|
|
35
46
|
/**
|
|
36
|
-
* creates a cumulative notification by adding a change notification at the end of the call stack
|
|
47
|
+
* creates a cumulative notification by adding a change notification at the end of the call stack
|
|
37
48
|
*/
|
|
38
49
|
notifyChangeCumulative(): void;
|
|
39
50
|
/**
|
|
40
|
-
* selects a state or a substate
|
|
51
|
+
* selects a state or a substate.
|
|
52
|
+
* supports an optional AbortSignal for automatic unsubscription.
|
|
53
|
+
* memoizes observables by selector function reference.
|
|
41
54
|
*/
|
|
42
|
-
select<T = TStatePayload>(selectorFn?: (state: TStatePayload) => T
|
|
55
|
+
select<T = TStatePayload>(selectorFn?: (state: TStatePayload) => T, options?: {
|
|
56
|
+
signal?: AbortSignal;
|
|
57
|
+
}): plugins.smartrx.rxjs.Observable<T>;
|
|
43
58
|
/**
|
|
44
59
|
* creates an action capable of modifying the state
|
|
45
60
|
*/
|
|
@@ -49,11 +64,13 @@ export declare class StatePart<TStatePartName, TStatePayload> {
|
|
|
49
64
|
*/
|
|
50
65
|
dispatchAction<T>(stateAction: StateAction<TStatePayload, T>, actionPayload: T): Promise<TStatePayload>;
|
|
51
66
|
/**
|
|
52
|
-
* waits until a certain part of the state becomes available
|
|
53
|
-
*
|
|
54
|
-
* @param timeoutMs - optional timeout in milliseconds to prevent indefinite waiting
|
|
67
|
+
* waits until a certain part of the state becomes available.
|
|
68
|
+
* supports optional timeout and AbortSignal.
|
|
55
69
|
*/
|
|
56
|
-
waitUntilPresent<T = TStatePayload>(selectorFn?: (state: TStatePayload) => T,
|
|
70
|
+
waitUntilPresent<T = TStatePayload>(selectorFn?: (state: TStatePayload) => T, optionsOrTimeout?: number | {
|
|
71
|
+
timeoutMs?: number;
|
|
72
|
+
signal?: AbortSignal;
|
|
73
|
+
}): Promise<T>;
|
|
57
74
|
/**
|
|
58
75
|
* is executed
|
|
59
76
|
*/
|
|
@@ -1,13 +1,36 @@
|
|
|
1
1
|
import * as plugins from './smartstate.plugins.js';
|
|
2
|
+
import { Observable, shareReplay, takeUntil } from 'rxjs';
|
|
2
3
|
import { StateAction } from './smartstate.classes.stateaction.js';
|
|
4
|
+
/**
|
|
5
|
+
* creates an Observable that emits once when the given AbortSignal fires
|
|
6
|
+
*/
|
|
7
|
+
function fromAbortSignal(signal) {
|
|
8
|
+
return new Observable((subscriber) => {
|
|
9
|
+
if (signal.aborted) {
|
|
10
|
+
subscriber.next();
|
|
11
|
+
subscriber.complete();
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const handler = () => {
|
|
15
|
+
subscriber.next();
|
|
16
|
+
subscriber.complete();
|
|
17
|
+
};
|
|
18
|
+
signal.addEventListener('abort', handler);
|
|
19
|
+
return () => signal.removeEventListener('abort', handler);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
3
22
|
export class StatePart {
|
|
4
23
|
constructor(nameArg, webStoreOptionsArg) {
|
|
5
24
|
this.state = new plugins.smartrx.rxjs.Subject();
|
|
6
25
|
this.cumulativeDeferred = plugins.smartpromise.cumulativeDefer();
|
|
7
26
|
this.pendingCumulativeNotification = null;
|
|
8
|
-
this.
|
|
27
|
+
this.pendingBatchNotification = false;
|
|
28
|
+
this.webStore = null;
|
|
29
|
+
this.middlewares = [];
|
|
30
|
+
// Selector memoization
|
|
31
|
+
this.selectorCache = new WeakMap();
|
|
32
|
+
this.defaultSelectObservable = null;
|
|
9
33
|
this.name = nameArg;
|
|
10
|
-
// Initialize WebStore if webStoreOptions are provided
|
|
11
34
|
if (webStoreOptionsArg) {
|
|
12
35
|
this.webStoreOptions = webStoreOptionsArg;
|
|
13
36
|
}
|
|
@@ -32,31 +55,46 @@ export class StatePart {
|
|
|
32
55
|
getState() {
|
|
33
56
|
return this.stateStore;
|
|
34
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* adds a middleware that intercepts setState calls.
|
|
60
|
+
* middleware can transform the state or throw to reject it.
|
|
61
|
+
* returns a removal function.
|
|
62
|
+
*/
|
|
63
|
+
addMiddleware(middleware) {
|
|
64
|
+
this.middlewares.push(middleware);
|
|
65
|
+
return () => {
|
|
66
|
+
const idx = this.middlewares.indexOf(middleware);
|
|
67
|
+
if (idx !== -1) {
|
|
68
|
+
this.middlewares.splice(idx, 1);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
35
72
|
/**
|
|
36
73
|
* sets the stateStore to the new state
|
|
37
|
-
* @param newStateArg
|
|
38
74
|
*/
|
|
39
75
|
async setState(newStateArg) {
|
|
76
|
+
// Run middleware chain
|
|
77
|
+
let processedState = newStateArg;
|
|
78
|
+
for (const mw of this.middlewares) {
|
|
79
|
+
processedState = await mw(processedState, this.stateStore);
|
|
80
|
+
}
|
|
40
81
|
// Validate state structure
|
|
41
|
-
if (!this.validateState(
|
|
82
|
+
if (!this.validateState(processedState)) {
|
|
42
83
|
throw new Error(`Invalid state structure for state part '${this.name}'`);
|
|
43
84
|
}
|
|
44
|
-
// Save to WebStore first to ensure atomicity
|
|
85
|
+
// Save to WebStore first to ensure atomicity
|
|
45
86
|
if (this.webStore) {
|
|
46
|
-
await this.webStore.set(String(this.name),
|
|
87
|
+
await this.webStore.set(String(this.name), processedState);
|
|
47
88
|
}
|
|
48
89
|
// Update in-memory state after successful persistence
|
|
49
|
-
this.stateStore =
|
|
90
|
+
this.stateStore = processedState;
|
|
50
91
|
await this.notifyChange();
|
|
51
92
|
return this.stateStore;
|
|
52
93
|
}
|
|
53
94
|
/**
|
|
54
95
|
* Validates state structure - can be overridden for custom validation
|
|
55
|
-
* @param stateArg
|
|
56
96
|
*/
|
|
57
97
|
validateState(stateArg) {
|
|
58
|
-
// Basic validation - ensure state is not null/undefined
|
|
59
|
-
// Subclasses can override for more specific validation
|
|
60
98
|
return stateArg !== null && stateArg !== undefined;
|
|
61
99
|
}
|
|
62
100
|
/**
|
|
@@ -66,6 +104,12 @@ export class StatePart {
|
|
|
66
104
|
if (!this.stateStore) {
|
|
67
105
|
return;
|
|
68
106
|
}
|
|
107
|
+
// If inside a batch, defer the notification
|
|
108
|
+
if (this.smartstateRef?.isBatching) {
|
|
109
|
+
this.pendingBatchNotification = true;
|
|
110
|
+
this.smartstateRef.registerPendingNotification(this);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
69
113
|
const createStateHash = async (stateArg) => {
|
|
70
114
|
return await plugins.smarthashWeb.sha256FromString(plugins.smartjson.stableOneWayStringify(stateArg));
|
|
71
115
|
};
|
|
@@ -80,10 +124,9 @@ export class StatePart {
|
|
|
80
124
|
this.state.next(this.stateStore);
|
|
81
125
|
}
|
|
82
126
|
/**
|
|
83
|
-
* creates a cumulative notification by adding a change notification at the end of the call stack
|
|
127
|
+
* creates a cumulative notification by adding a change notification at the end of the call stack
|
|
84
128
|
*/
|
|
85
129
|
notifyChangeCumulative() {
|
|
86
|
-
// Debounce: clear any pending notification
|
|
87
130
|
if (this.pendingCumulativeNotification) {
|
|
88
131
|
clearTimeout(this.pendingCumulativeNotification);
|
|
89
132
|
}
|
|
@@ -95,22 +138,46 @@ export class StatePart {
|
|
|
95
138
|
}, 0);
|
|
96
139
|
}
|
|
97
140
|
/**
|
|
98
|
-
* selects a state or a substate
|
|
141
|
+
* selects a state or a substate.
|
|
142
|
+
* supports an optional AbortSignal for automatic unsubscription.
|
|
143
|
+
* memoizes observables by selector function reference.
|
|
99
144
|
*/
|
|
100
|
-
select(selectorFn) {
|
|
101
|
-
|
|
102
|
-
|
|
145
|
+
select(selectorFn, options) {
|
|
146
|
+
const hasSignal = options?.signal != null;
|
|
147
|
+
// Check memoization cache (only for non-signal selects)
|
|
148
|
+
if (!hasSignal) {
|
|
149
|
+
if (!selectorFn) {
|
|
150
|
+
if (this.defaultSelectObservable) {
|
|
151
|
+
return this.defaultSelectObservable;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else if (this.selectorCache.has(selectorFn)) {
|
|
155
|
+
return this.selectorCache.get(selectorFn);
|
|
156
|
+
}
|
|
103
157
|
}
|
|
104
|
-
const
|
|
158
|
+
const effectiveSelectorFn = selectorFn || ((state) => state);
|
|
159
|
+
let mapped = this.state.pipe(plugins.smartrx.rxjs.ops.startWith(this.getState()), plugins.smartrx.rxjs.ops.filter((stateArg) => stateArg !== undefined), plugins.smartrx.rxjs.ops.map((stateArg) => {
|
|
105
160
|
try {
|
|
106
|
-
return
|
|
161
|
+
return effectiveSelectorFn(stateArg);
|
|
107
162
|
}
|
|
108
163
|
catch (e) {
|
|
109
164
|
console.error(`Selector error in state part '${this.name}':`, e);
|
|
110
165
|
return undefined;
|
|
111
166
|
}
|
|
112
167
|
}));
|
|
113
|
-
|
|
168
|
+
if (hasSignal) {
|
|
169
|
+
mapped = mapped.pipe(takeUntil(fromAbortSignal(options.signal)));
|
|
170
|
+
return mapped;
|
|
171
|
+
}
|
|
172
|
+
// Apply shareReplay for caching and store in memo cache
|
|
173
|
+
const shared = mapped.pipe(shareReplay({ bufferSize: 1, refCount: true }));
|
|
174
|
+
if (!selectorFn) {
|
|
175
|
+
this.defaultSelectObservable = shared;
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
this.selectorCache.set(selectorFn, shared);
|
|
179
|
+
}
|
|
180
|
+
return shared;
|
|
114
181
|
}
|
|
115
182
|
/**
|
|
116
183
|
* creates an action capable of modifying the state
|
|
@@ -128,14 +195,27 @@ export class StatePart {
|
|
|
128
195
|
return this.getState();
|
|
129
196
|
}
|
|
130
197
|
/**
|
|
131
|
-
* waits until a certain part of the state becomes available
|
|
132
|
-
*
|
|
133
|
-
* @param timeoutMs - optional timeout in milliseconds to prevent indefinite waiting
|
|
198
|
+
* waits until a certain part of the state becomes available.
|
|
199
|
+
* supports optional timeout and AbortSignal.
|
|
134
200
|
*/
|
|
135
|
-
async waitUntilPresent(selectorFn,
|
|
201
|
+
async waitUntilPresent(selectorFn, optionsOrTimeout) {
|
|
202
|
+
// Parse backward-compatible args
|
|
203
|
+
let timeoutMs;
|
|
204
|
+
let signal;
|
|
205
|
+
if (typeof optionsOrTimeout === 'number') {
|
|
206
|
+
timeoutMs = optionsOrTimeout;
|
|
207
|
+
}
|
|
208
|
+
else if (optionsOrTimeout) {
|
|
209
|
+
timeoutMs = optionsOrTimeout.timeoutMs;
|
|
210
|
+
signal = optionsOrTimeout.signal;
|
|
211
|
+
}
|
|
136
212
|
const done = plugins.smartpromise.defer();
|
|
137
213
|
const selectedObservable = this.select(selectorFn);
|
|
138
214
|
let resolved = false;
|
|
215
|
+
// Check if already aborted
|
|
216
|
+
if (signal?.aborted) {
|
|
217
|
+
throw new Error('Aborted');
|
|
218
|
+
}
|
|
139
219
|
const subscription = selectedObservable.subscribe((value) => {
|
|
140
220
|
if (value && !resolved) {
|
|
141
221
|
resolved = true;
|
|
@@ -152,6 +232,19 @@ export class StatePart {
|
|
|
152
232
|
}
|
|
153
233
|
}, timeoutMs);
|
|
154
234
|
}
|
|
235
|
+
// Handle abort signal
|
|
236
|
+
const abortHandler = signal ? () => {
|
|
237
|
+
if (!resolved) {
|
|
238
|
+
resolved = true;
|
|
239
|
+
subscription.unsubscribe();
|
|
240
|
+
if (timeoutId)
|
|
241
|
+
clearTimeout(timeoutId);
|
|
242
|
+
done.reject(new Error('Aborted'));
|
|
243
|
+
}
|
|
244
|
+
} : undefined;
|
|
245
|
+
if (signal && abortHandler) {
|
|
246
|
+
signal.addEventListener('abort', abortHandler);
|
|
247
|
+
}
|
|
155
248
|
try {
|
|
156
249
|
const result = await done.promise;
|
|
157
250
|
return result;
|
|
@@ -160,6 +253,9 @@ export class StatePart {
|
|
|
160
253
|
subscription.unsubscribe();
|
|
161
254
|
if (timeoutId)
|
|
162
255
|
clearTimeout(timeoutId);
|
|
256
|
+
if (signal && abortHandler) {
|
|
257
|
+
signal.removeEventListener('abort', abortHandler);
|
|
258
|
+
}
|
|
163
259
|
}
|
|
164
260
|
}
|
|
165
261
|
/**
|
|
@@ -171,4 +267,4 @@ export class StatePart {
|
|
|
171
267
|
await this.setState(await resultPromise);
|
|
172
268
|
}
|
|
173
269
|
}
|
|
174
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzdGF0ZS5jbGFzc2VzLnN0YXRlcGFydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0c3RhdGUuY2xhc3Nlcy5zdGF0ZXBhcnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSx5QkFBeUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsV0FBVyxFQUFtQixNQUFNLHFDQUFxQyxDQUFDO0FBRW5GLE1BQU0sT0FBTyxTQUFTO0lBV3BCLFlBQVksT0FBdUIsRUFBRSxrQkFBc0Q7UUFUcEYsVUFBSyxHQUFHLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFpQixDQUFDO1FBRXpELHVCQUFrQixHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsZUFBZSxFQUFFLENBQUM7UUFFNUQsa0NBQTZCLEdBQXlDLElBQUksQ0FBQztRQUczRSxhQUFRLEdBQW9ELElBQUksQ0FBQyxDQUFDLHdCQUF3QjtRQUdoRyxJQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQztRQUVwQixzREFBc0Q7UUFDdEQsSUFBSSxrQkFBa0IsRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxlQUFlLEdBQUcsa0JBQWtCLENBQUM7UUFDNUMsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxJQUFJO1FBQ2YsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDekIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFnQixJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDbkYsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQzNCLE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQy9E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
|
|
270
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzdGF0ZS5jbGFzc2VzLnN0YXRlcGFydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0c3RhdGUuY2xhc3Nlcy5zdGF0ZXBhcnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSx5QkFBeUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDMUQsT0FBTyxFQUFFLFdBQVcsRUFBbUIsTUFBTSxxQ0FBcUMsQ0FBQztBQVFuRjs7R0FFRztBQUNILFNBQVMsZUFBZSxDQUFDLE1BQW1CO0lBQzFDLE9BQU8sSUFBSSxVQUFVLENBQU8sQ0FBQyxVQUFVLEVBQUUsRUFBRTtRQUN6QyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNuQixVQUFVLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDbEIsVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3RCLE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsR0FBRyxFQUFFO1lBQ25CLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNsQixVQUFVLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDeEIsQ0FBQyxDQUFDO1FBQ0YsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztRQUMxQyxPQUFPLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDNUQsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsTUFBTSxPQUFPLFNBQVM7SUFtQnBCLFlBQVksT0FBdUIsRUFBRSxrQkFBc0Q7UUFqQnBGLFVBQUssR0FBRyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBaUIsQ0FBQztRQUd6RCx1QkFBa0IsR0FBRyxPQUFPLENBQUMs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
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { StatePart } from './smartstate.classes.statepart.js';
|
|
2
|
+
export interface IContextProviderOptions<TPayload> {
|
|
3
|
+
/** the context key (compared by strict equality) */
|
|
4
|
+
context: unknown;
|
|
5
|
+
/** the state part to provide */
|
|
6
|
+
statePart: StatePart<any, TPayload>;
|
|
7
|
+
/** optional selector to provide a derived value instead of the full state */
|
|
8
|
+
selectorFn?: (state: TPayload) => any;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* attaches a Context Protocol provider to an HTML element.
|
|
12
|
+
* listens for `context-request` events and responds with the state part's value.
|
|
13
|
+
* if subscribe=true, retains the callback and invokes it on every state change.
|
|
14
|
+
* returns a cleanup function that removes the listener and unsubscribes.
|
|
15
|
+
*/
|
|
16
|
+
export declare function attachContextProvider<TPayload>(element: HTMLElement, options: IContextProviderOptions<TPayload>): () => void;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* attaches a Context Protocol provider to an HTML element.
|
|
3
|
+
* listens for `context-request` events and responds with the state part's value.
|
|
4
|
+
* if subscribe=true, retains the callback and invokes it on every state change.
|
|
5
|
+
* returns a cleanup function that removes the listener and unsubscribes.
|
|
6
|
+
*/
|
|
7
|
+
export function attachContextProvider(element, options) {
|
|
8
|
+
const { context, statePart, selectorFn } = options;
|
|
9
|
+
const subscribers = new Set();
|
|
10
|
+
const subscription = statePart.select(selectorFn).subscribe((value) => {
|
|
11
|
+
for (const cb of subscribers) {
|
|
12
|
+
cb(value);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
const getValue = () => {
|
|
16
|
+
const state = statePart.getState();
|
|
17
|
+
if (state === undefined)
|
|
18
|
+
return undefined;
|
|
19
|
+
return selectorFn ? selectorFn(state) : state;
|
|
20
|
+
};
|
|
21
|
+
const handler = (event) => {
|
|
22
|
+
const e = event;
|
|
23
|
+
const detail = e.detail;
|
|
24
|
+
if (!detail || detail.context !== context)
|
|
25
|
+
return;
|
|
26
|
+
e.stopPropagation();
|
|
27
|
+
if (detail.subscribe) {
|
|
28
|
+
const cb = detail.callback;
|
|
29
|
+
subscribers.add(cb);
|
|
30
|
+
const unsubscribe = () => subscribers.delete(cb);
|
|
31
|
+
cb(getValue(), unsubscribe);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
detail.callback(getValue());
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
element.addEventListener('context-request', handler);
|
|
38
|
+
return () => {
|
|
39
|
+
element.removeEventListener('context-request', handler);
|
|
40
|
+
subscription.unsubscribe();
|
|
41
|
+
subscribers.clear();
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzdGF0ZS5jb250ZXh0cHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydHN0YXRlLmNvbnRleHRwcm92aWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFXQTs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxxQkFBcUIsQ0FDbkMsT0FBb0IsRUFDcEIsT0FBMEM7SUFFMUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLEdBQUcsT0FBTyxDQUFDO0lBQ25ELE1BQU0sV0FBVyxHQUFHLElBQUksR0FBRyxFQUFrRCxDQUFDO0lBRTlFLE1BQU0sWUFBWSxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7UUFDcEUsS0FBSyxNQUFNLEVBQUUsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUM3QixFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDWixDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFSCxNQUFNLFFBQVEsR0FBRyxHQUFRLEVBQUU7UUFDekIsTUFBTSxLQUFLLEdBQUcsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ25DLElBQUksS0FBSyxLQUFLLFNBQVM7WUFBRSxPQUFPLFNBQVMsQ0FBQztRQUMxQyxPQUFPLFVBQVUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFDaEQsQ0FBQyxDQUFDO0lBRUYsTUFBTSxPQUFPLEdBQUcsQ0FBQyxLQUFZLEVBQUUsRUFBRTtRQUMvQixNQUFNLENBQUMsR0FBRyxLQUFvQixDQUFDO1FBQy9CLE1BQU0sTUFBTSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFDeEIsSUFBSSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsT0FBTyxLQUFLLE9BQU87WUFBRSxPQUFPO1FBRWxELENBQUMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUVwQixJQUFJLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNyQixNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDO1lBQzNCLFdBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDcEIsTUFBTSxXQUFXLEdBQUcsR0FBRyxFQUFFLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNqRCxFQUFFLENBQUMsUUFBUSxFQUFFLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDOUIsQ0FBQzthQUFNLENBQUM7WUFDTixNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDOUIsQ0FBQztJQUNILENBQUMsQ0FBQztJQUVGLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxpQkFBaUIsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUVyRCxPQUFPLEdBQUcsRUFBRTtRQUNWLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxpQkFBaUIsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUN4RCxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDM0IsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3RCLENBQUMsQ0FBQztBQUNKLENBQUMifQ==
|