@netless/window-manager 0.4.73-beta.0 → 0.4.73-beta.1
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/index.d.ts +1087 -38
- package/dist/index.js +14 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +130 -40
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
- package/src/App/AppContext.ts +13 -5
- package/src/App/AppProxy.ts +2 -2
- package/src/App/MagixEvent/index.ts +38 -38
- package/src/App/Storage/StorageEvent.ts +13 -13
- package/src/App/Storage/index.ts +265 -242
- package/src/App/Storage/typings.ts +4 -2
- package/src/App/Storage/utils.ts +3 -3
- package/src/AppListener.ts +5 -5
- package/src/AttributesDelegate.ts +5 -7
- package/src/BoxEmitter.ts +12 -6
- package/src/BoxManager.ts +1 -1
- package/src/ContainerResizeObserver.ts +1 -1
- package/src/Helper.ts +67 -15
- package/src/InternalEmitter.ts +4 -3
- package/src/Page/index.ts +1 -1
- package/src/Register/index.ts +5 -7
- package/src/Register/loader.ts +1 -1
- package/src/Register/storage.ts +13 -13
- package/src/Utils/Common.ts +10 -5
- package/src/Utils/Reactive.ts +26 -25
- package/src/Utils/RoomHacker.ts +1 -1
- package/src/Utils/error.ts +0 -1
- package/src/View/IframeBridge.ts +627 -583
- package/src/View/MainView.ts +7 -2
- package/src/callback.ts +7 -1
- package/src/index.ts +8 -21
- package/src/typings.ts +11 -6
- package/dist/App/AppContext.d.ts +0 -79
- package/dist/App/AppPageStateImpl.d.ts +0 -17
- package/dist/App/AppProxy.d.ts +0 -67
- package/dist/App/MagixEvent/index.d.ts +0 -29
- package/dist/App/Storage/StorageEvent.d.ts +0 -8
- package/dist/App/Storage/index.d.ts +0 -39
- package/dist/App/Storage/typings.d.ts +0 -22
- package/dist/App/Storage/utils.d.ts +0 -5
- package/dist/App/index.d.ts +0 -2
- package/dist/AppListener.d.ts +0 -21
- package/dist/AppManager.d.ts +0 -110
- package/dist/AttributesDelegate.d.ts +0 -91
- package/dist/BoxEmitter.d.ts +0 -34
- package/dist/BoxManager.d.ts +0 -98
- package/dist/BuiltinApps.d.ts +0 -5
- package/dist/ContainerResizeObserver.d.ts +0 -11
- package/dist/Cursor/Cursor.d.ts +0 -43
- package/dist/Cursor/icons.d.ts +0 -3
- package/dist/Cursor/icons2.d.ts +0 -4
- package/dist/Cursor/index.d.ts +0 -55
- package/dist/Helper.d.ts +0 -11
- package/dist/InternalEmitter.d.ts +0 -34
- package/dist/Page/PageController.d.ts +0 -21
- package/dist/Page/index.d.ts +0 -3
- package/dist/PageState.d.ts +0 -9
- package/dist/ReconnectRefresher.d.ts +0 -24
- package/dist/RedoUndo.d.ts +0 -18
- package/dist/Register/index.d.ts +0 -28
- package/dist/Register/loader.d.ts +0 -4
- package/dist/Register/storage.d.ts +0 -8
- package/dist/Utils/AppCreateQueue.d.ts +0 -15
- package/dist/Utils/Common.d.ts +0 -22
- package/dist/Utils/Reactive.d.ts +0 -6
- package/dist/Utils/RoomHacker.d.ts +0 -3
- package/dist/Utils/error.d.ts +0 -27
- package/dist/Utils/log.d.ts +0 -1
- package/dist/View/IframeBridge.d.ts +0 -146
- package/dist/View/MainView.d.ts +0 -58
- package/dist/View/ViewManager.d.ts +0 -13
- package/dist/callback.d.ts +0 -38
- package/dist/constants.d.ts +0 -48
- package/dist/typings.d.ts +0 -84
package/src/App/Storage/index.ts
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
import type { AkkoObjectUpdatedProperty } from "white-web-sdk";
|
2
2
|
import type { AppContext } from "../AppContext";
|
3
|
-
import type {
|
3
|
+
import type {
|
4
|
+
Diff,
|
5
|
+
MaybeRefValue,
|
6
|
+
RefValue,
|
7
|
+
StorageStateChangedEvent,
|
8
|
+
StorageStateChangedListener,
|
9
|
+
StorageStateChangedListenerDisposer,
|
10
|
+
} from "./typings";
|
4
11
|
|
5
12
|
import { get, has, isObject, mapValues, noop, size } from "lodash";
|
6
13
|
import { SideEffectManager } from "side-effect-manager";
|
@@ -8,289 +15,305 @@ import { safeListenPropsUpdated } from "../../Utils/Reactive";
|
|
8
15
|
import { StorageEvent } from "./StorageEvent";
|
9
16
|
import { isRef, makeRef, plainObjectKeys } from "./utils";
|
10
17
|
|
11
|
-
export * from
|
18
|
+
export * from "./typings";
|
12
19
|
|
13
20
|
export const STORAGE_NS = "_WM-STORAGE_";
|
14
21
|
|
15
22
|
export class Storage<TState extends Record<string, any> = any> implements Storage<TState> {
|
16
|
-
|
23
|
+
readonly id: string | null;
|
17
24
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
25
|
+
private readonly _context: AppContext;
|
26
|
+
private readonly _sideEffect = new SideEffectManager();
|
27
|
+
private _state: TState;
|
28
|
+
private _destroyed = false;
|
22
29
|
|
23
|
-
|
30
|
+
private _refMap = new WeakMap<any, RefValue>();
|
24
31
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
32
|
+
/**
|
33
|
+
* `setState` alters local state immediately before sending to server. This will cache the old value for onStateChanged diffing.
|
34
|
+
*/
|
35
|
+
private _lastValue = new Map<string | number | symbol, TState[Extract<keyof TState, string>]>();
|
29
36
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
37
|
+
constructor(context: AppContext, id?: string, defaultState?: TState) {
|
38
|
+
if (defaultState && !isObject(defaultState)) {
|
39
|
+
throw new Error(`Default state for Storage ${id} is not an object.`);
|
40
|
+
}
|
34
41
|
|
35
|
-
|
36
|
-
|
42
|
+
this._context = context;
|
43
|
+
this.id = id || null;
|
37
44
|
|
38
|
-
|
39
|
-
|
45
|
+
this._state = {} as TState;
|
46
|
+
const rawState = this._getRawState(this._state);
|
40
47
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
48
|
+
if (this._context.getIsWritable()) {
|
49
|
+
if (this.id === null) {
|
50
|
+
if (context.isAddApp && defaultState) {
|
51
|
+
this.setState(defaultState);
|
52
|
+
}
|
53
|
+
} else {
|
54
|
+
if (rawState === this._state || !isObject(rawState)) {
|
55
|
+
if (!get(this._context.getAttributes(), [STORAGE_NS])) {
|
56
|
+
this._context.updateAttributes([STORAGE_NS], {});
|
57
|
+
}
|
58
|
+
this._context.updateAttributes([STORAGE_NS, this.id], this._state);
|
59
|
+
if (defaultState) {
|
60
|
+
this.setState(defaultState);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
55
64
|
}
|
56
|
-
|
65
|
+
|
66
|
+
// strip mobx
|
67
|
+
plainObjectKeys(rawState).forEach(key => {
|
68
|
+
if (this.id === null && key === STORAGE_NS) {
|
69
|
+
return;
|
70
|
+
}
|
71
|
+
try {
|
72
|
+
const rawValue = isObject(rawState[key])
|
73
|
+
? JSON.parse(JSON.stringify(rawState[key]))
|
74
|
+
: rawState[key];
|
75
|
+
if (isRef<TState[Extract<keyof TState, string>]>(rawValue)) {
|
76
|
+
this._state[key] = rawValue.v;
|
77
|
+
if (isObject(rawValue.v)) {
|
78
|
+
this._refMap.set(rawValue.v, rawValue);
|
79
|
+
}
|
80
|
+
} else {
|
81
|
+
this._state[key] = rawValue;
|
82
|
+
}
|
83
|
+
} catch (e) {
|
84
|
+
console.error(e);
|
85
|
+
}
|
86
|
+
});
|
87
|
+
|
88
|
+
this._sideEffect.addDisposer(
|
89
|
+
safeListenPropsUpdated(
|
90
|
+
() =>
|
91
|
+
this.id === null
|
92
|
+
? context.getAttributes()
|
93
|
+
: get(context.getAttributes(), [STORAGE_NS, this.id]),
|
94
|
+
this._updateProperties.bind(this),
|
95
|
+
this.destroy.bind(this)
|
96
|
+
)
|
97
|
+
);
|
57
98
|
}
|
58
99
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
return;
|
63
|
-
}
|
64
|
-
try {
|
65
|
-
const rawValue = isObject(rawState[key]) ? JSON.parse(JSON.stringify(rawState[key])) : rawState[key];
|
66
|
-
if (isRef<TState[Extract<keyof TState, string>]>(rawValue)) {
|
67
|
-
this._state[key] = rawValue.v;
|
68
|
-
if (isObject(rawValue.v)) {
|
69
|
-
this._refMap.set(rawValue.v, rawValue);
|
70
|
-
}
|
71
|
-
} else {
|
72
|
-
this._state[key] = rawValue;
|
100
|
+
get state(): Readonly<TState> {
|
101
|
+
if (this._destroyed) {
|
102
|
+
console.warn(`Accessing state on destroyed Storage "${this.id}"`);
|
73
103
|
}
|
74
|
-
|
75
|
-
console.error(e);
|
76
|
-
}
|
77
|
-
});
|
78
|
-
|
79
|
-
this._sideEffect.addDisposer(
|
80
|
-
safeListenPropsUpdated(
|
81
|
-
() => this.id === null ? context.getAttributes() : get(context.getAttributes(), [STORAGE_NS, this.id]),
|
82
|
-
this._updateProperties.bind(this),
|
83
|
-
this.destroy.bind(this)
|
84
|
-
)
|
85
|
-
);
|
86
|
-
}
|
87
|
-
|
88
|
-
get state(): Readonly<TState> {
|
89
|
-
if (this._destroyed) {
|
90
|
-
console.warn(`Accessing state on destroyed Storage "${this.id}"`)
|
104
|
+
return this._state;
|
91
105
|
}
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
}
|
101
|
-
|
102
|
-
ensureState(state: Partial<TState>): void {
|
103
|
-
return this.setState(
|
104
|
-
plainObjectKeys(state).reduce((payload, key) => {
|
105
|
-
if (!has(this._state, key)) {
|
106
|
-
payload[key] = state[key];
|
107
|
-
}
|
108
|
-
return payload;
|
109
|
-
}, {} as Partial<TState>)
|
110
|
-
);
|
111
|
-
}
|
112
|
-
|
113
|
-
setState(state: Partial<TState>): void {
|
114
|
-
if (this._destroyed) {
|
115
|
-
console.error(new Error(`Cannot call setState on destroyed Storage "${this.id}".`));
|
116
|
-
return;
|
106
|
+
|
107
|
+
readonly onStateChanged = new StorageEvent<StorageStateChangedEvent<TState>>();
|
108
|
+
|
109
|
+
addStateChangedListener(
|
110
|
+
handler: StorageStateChangedListener<TState>
|
111
|
+
): StorageStateChangedListenerDisposer {
|
112
|
+
this.onStateChanged.addListener(handler);
|
113
|
+
return () => this.onStateChanged.removeListener(handler);
|
117
114
|
}
|
118
115
|
|
119
|
-
|
120
|
-
|
121
|
-
|
116
|
+
ensureState(state: Partial<TState>): void {
|
117
|
+
return this.setState(
|
118
|
+
plainObjectKeys(state).reduce((payload, key) => {
|
119
|
+
if (!has(this._state, key)) {
|
120
|
+
payload[key] = state[key];
|
121
|
+
}
|
122
|
+
return payload;
|
123
|
+
}, {} as Partial<TState>)
|
124
|
+
);
|
122
125
|
}
|
123
126
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
if (value === this._state[key]) {
|
129
|
-
return;
|
127
|
+
setState(state: Partial<TState>): void {
|
128
|
+
if (this._destroyed) {
|
129
|
+
console.error(new Error(`Cannot call setState on destroyed Storage "${this.id}".`));
|
130
|
+
return;
|
130
131
|
}
|
131
132
|
|
132
|
-
if (
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
payload = refValue;
|
148
|
-
}
|
133
|
+
if (!this._context.getIsWritable()) {
|
134
|
+
console.error(
|
135
|
+
new Error(`Cannot setState on Storage "${this.id}" without writable access`),
|
136
|
+
state
|
137
|
+
);
|
138
|
+
return;
|
139
|
+
}
|
140
|
+
|
141
|
+
const keys = plainObjectKeys(state);
|
142
|
+
if (keys.length > 0) {
|
143
|
+
keys.forEach(key => {
|
144
|
+
const value = state[key];
|
145
|
+
if (value === this._state[key]) {
|
146
|
+
return;
|
147
|
+
}
|
149
148
|
|
150
|
-
|
149
|
+
if (value === void 0) {
|
150
|
+
this._lastValue.set(key, this._state[key]);
|
151
|
+
delete this._state[key];
|
152
|
+
this._setRawState(key, value);
|
153
|
+
} else {
|
154
|
+
this._lastValue.set(key, this._state[key]);
|
155
|
+
this._state[key] = value as TState[Extract<keyof TState, string>];
|
156
|
+
|
157
|
+
let payload: MaybeRefValue<typeof value> = value;
|
158
|
+
if (isObject(value)) {
|
159
|
+
let refValue = this._refMap.get(value);
|
160
|
+
if (!refValue) {
|
161
|
+
refValue = makeRef(value);
|
162
|
+
this._refMap.set(value, refValue);
|
163
|
+
}
|
164
|
+
payload = refValue;
|
165
|
+
}
|
166
|
+
|
167
|
+
this._setRawState(key, payload);
|
168
|
+
}
|
169
|
+
});
|
151
170
|
}
|
152
|
-
});
|
153
|
-
}
|
154
|
-
}
|
155
|
-
|
156
|
-
/**
|
157
|
-
* Empty storage data.
|
158
|
-
*/
|
159
|
-
emptyStorage(): void {
|
160
|
-
if (size(this._state) <= 0) {
|
161
|
-
return;
|
162
171
|
}
|
163
172
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
173
|
+
/**
|
174
|
+
* Empty storage data.
|
175
|
+
*/
|
176
|
+
emptyStorage(): void {
|
177
|
+
if (size(this._state) <= 0) {
|
178
|
+
return;
|
179
|
+
}
|
168
180
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
181
|
+
if (this._destroyed) {
|
182
|
+
console.error(new Error(`Cannot empty destroyed Storage "${this.id}".`));
|
183
|
+
return;
|
184
|
+
}
|
173
185
|
|
174
|
-
|
175
|
-
|
186
|
+
if (!this._context.getIsWritable()) {
|
187
|
+
console.error(new Error(`Cannot empty Storage "${this.id}" without writable access.`));
|
188
|
+
return;
|
189
|
+
}
|
176
190
|
|
177
|
-
|
178
|
-
* Delete storage index with all of its data and destroy the Storage instance.
|
179
|
-
*/
|
180
|
-
deleteStorage(): void {
|
181
|
-
if (this.id === null) {
|
182
|
-
throw new Error(`Cannot delete main Storage`);
|
191
|
+
this.setState(mapValues(this._state, noop as () => undefined));
|
183
192
|
}
|
184
193
|
|
185
|
-
|
186
|
-
|
187
|
-
|
194
|
+
/**
|
195
|
+
* Delete storage index with all of its data and destroy the Storage instance.
|
196
|
+
*/
|
197
|
+
deleteStorage(): void {
|
198
|
+
if (this.id === null) {
|
199
|
+
throw new Error(`Cannot delete main Storage`);
|
200
|
+
}
|
201
|
+
|
202
|
+
if (!this._context.getIsWritable()) {
|
203
|
+
console.error(new Error(`Cannot delete Storage "${this.id}" without writable access.`));
|
204
|
+
return;
|
205
|
+
}
|
206
|
+
|
207
|
+
this.destroy();
|
208
|
+
|
209
|
+
this._context.updateAttributes([STORAGE_NS, this.id], void 0);
|
188
210
|
}
|
189
211
|
|
190
|
-
|
191
|
-
|
192
|
-
this._context.updateAttributes([STORAGE_NS, this.id], void 0);
|
193
|
-
}
|
194
|
-
|
195
|
-
get destroyed(): boolean {
|
196
|
-
return this._destroyed;
|
197
|
-
}
|
198
|
-
|
199
|
-
/**
|
200
|
-
* Destroy the Storage instance. The data will be kept.
|
201
|
-
*/
|
202
|
-
destroy() {
|
203
|
-
this._destroyed = true;
|
204
|
-
this._sideEffect.flushAll();
|
205
|
-
}
|
206
|
-
|
207
|
-
private _getRawState(): TState | undefined
|
208
|
-
private _getRawState(defaultValue: TState): TState
|
209
|
-
private _getRawState(defaultValue?: TState): TState | undefined {
|
210
|
-
if (this.id === null) {
|
211
|
-
return this._context.getAttributes() ?? defaultValue;
|
212
|
-
} else {
|
213
|
-
return get(this._context.getAttributes(), [STORAGE_NS, this.id], defaultValue);
|
212
|
+
get destroyed(): boolean {
|
213
|
+
return this._destroyed;
|
214
214
|
}
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
return this._context.updateAttributes([key], value);
|
223
|
-
} else {
|
224
|
-
return this._context.updateAttributes([STORAGE_NS, this.id, key], value);
|
215
|
+
|
216
|
+
/**
|
217
|
+
* Destroy the Storage instance. The data will be kept.
|
218
|
+
*/
|
219
|
+
destroy() {
|
220
|
+
this._destroyed = true;
|
221
|
+
this._sideEffect.flushAll();
|
225
222
|
}
|
226
|
-
}
|
227
223
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
224
|
+
private _getRawState(): TState | undefined;
|
225
|
+
private _getRawState(defaultValue: TState): TState;
|
226
|
+
private _getRawState(defaultValue?: TState): TState | undefined {
|
227
|
+
if (this.id === null) {
|
228
|
+
return this._context.getAttributes() ?? defaultValue;
|
229
|
+
} else {
|
230
|
+
return get(this._context.getAttributes(), [STORAGE_NS, this.id], defaultValue);
|
231
|
+
}
|
232
232
|
}
|
233
233
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
try {
|
239
|
-
const action = actions[i]
|
240
|
-
const key = action.key as Extract<keyof TState, string>;
|
241
|
-
|
242
|
-
if (this.id === null && key === STORAGE_NS) {
|
243
|
-
continue
|
244
|
-
}
|
245
|
-
|
246
|
-
const value = isObject(action.value) ? JSON.parse(JSON.stringify(action.value)) : action.value;
|
247
|
-
let oldValue: TState[Extract<keyof TState, string>] | undefined;
|
248
|
-
if (this._lastValue.has(key)) {
|
249
|
-
oldValue = this._lastValue.get(key);
|
250
|
-
this._lastValue.delete(key);
|
251
|
-
}
|
252
|
-
|
253
|
-
switch (action.kind) {
|
254
|
-
case 2: {
|
255
|
-
// Removed
|
256
|
-
if (has(this._state, key)) {
|
257
|
-
oldValue = this._state[key];
|
258
|
-
delete this._state[key];
|
259
|
-
}
|
260
|
-
diffs[key] = { oldValue };
|
261
|
-
break;
|
234
|
+
private _setRawState(key: string, value: any): void {
|
235
|
+
if (this.id === null) {
|
236
|
+
if (key === STORAGE_NS) {
|
237
|
+
throw new Error(`Cannot set attribute internal filed "${STORAGE_NS}"`);
|
262
238
|
}
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
const curValue = this._state[key];
|
269
|
-
if (isObject(curValue) && this._refMap.get(curValue)?.k === k) {
|
270
|
-
newValue = curValue;
|
271
|
-
} else {
|
272
|
-
newValue = v;
|
273
|
-
if (isObject(v)) {
|
274
|
-
this._refMap.set(v, value);
|
275
|
-
}
|
276
|
-
}
|
277
|
-
}
|
239
|
+
return this._context.updateAttributes([key], value);
|
240
|
+
} else {
|
241
|
+
return this._context.updateAttributes([STORAGE_NS, this.id, key], value);
|
242
|
+
}
|
243
|
+
}
|
278
244
|
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
245
|
+
private _updateProperties(
|
246
|
+
actions: ReadonlyArray<AkkoObjectUpdatedProperty<TState, string>>
|
247
|
+
): void {
|
248
|
+
if (this._destroyed) {
|
249
|
+
console.error(
|
250
|
+
new Error(`Cannot call _updateProperties on destroyed Storage "${this.id}".`)
|
251
|
+
);
|
252
|
+
return;
|
253
|
+
}
|
283
254
|
|
284
|
-
|
285
|
-
|
255
|
+
if (actions.length > 0) {
|
256
|
+
const diffs: Diff<TState> = {};
|
257
|
+
|
258
|
+
for (let i = 0; i < actions.length; i++) {
|
259
|
+
try {
|
260
|
+
const action = actions[i];
|
261
|
+
const key = action.key as Extract<keyof TState, string>;
|
262
|
+
|
263
|
+
if (this.id === null && key === STORAGE_NS) {
|
264
|
+
continue;
|
265
|
+
}
|
266
|
+
|
267
|
+
const value = isObject(action.value)
|
268
|
+
? JSON.parse(JSON.stringify(action.value))
|
269
|
+
: action.value;
|
270
|
+
let oldValue: TState[Extract<keyof TState, string>] | undefined;
|
271
|
+
if (this._lastValue.has(key)) {
|
272
|
+
oldValue = this._lastValue.get(key);
|
273
|
+
this._lastValue.delete(key);
|
274
|
+
}
|
275
|
+
|
276
|
+
switch (action.kind) {
|
277
|
+
case 2: {
|
278
|
+
// Removed
|
279
|
+
if (has(this._state, key)) {
|
280
|
+
oldValue = this._state[key];
|
281
|
+
delete this._state[key];
|
282
|
+
}
|
283
|
+
diffs[key] = { oldValue };
|
284
|
+
break;
|
285
|
+
}
|
286
|
+
default: {
|
287
|
+
let newValue = value;
|
288
|
+
|
289
|
+
if (isRef<TState[Extract<keyof TState, string>]>(value)) {
|
290
|
+
const { k, v } = value;
|
291
|
+
const curValue = this._state[key];
|
292
|
+
if (isObject(curValue) && this._refMap.get(curValue)?.k === k) {
|
293
|
+
newValue = curValue;
|
294
|
+
} else {
|
295
|
+
newValue = v;
|
296
|
+
if (isObject(v)) {
|
297
|
+
this._refMap.set(v, value);
|
298
|
+
}
|
299
|
+
}
|
300
|
+
}
|
301
|
+
|
302
|
+
if (newValue !== this._state[key]) {
|
303
|
+
oldValue = this._state[key];
|
304
|
+
this._state[key] = newValue;
|
305
|
+
}
|
306
|
+
|
307
|
+
diffs[key] = { newValue, oldValue };
|
308
|
+
break;
|
309
|
+
}
|
310
|
+
}
|
311
|
+
} catch (e) {
|
312
|
+
console.error(e);
|
313
|
+
}
|
286
314
|
}
|
287
|
-
}
|
288
|
-
} catch (e) {
|
289
|
-
console.error(e)
|
290
|
-
}
|
291
|
-
}
|
292
315
|
|
293
|
-
|
316
|
+
this.onStateChanged.dispatch(diffs);
|
317
|
+
}
|
294
318
|
}
|
295
|
-
}
|
296
319
|
}
|
@@ -13,11 +13,13 @@ export type DiffOne<T> = { oldValue?: T; newValue?: T };
|
|
13
13
|
export type Diff<T> = { [K in keyof T]?: DiffOne<T[K]> };
|
14
14
|
|
15
15
|
export type StorageOnSetStatePayload<TState = unknown> = {
|
16
|
-
|
16
|
+
[K in keyof TState]?: MaybeRefValue<TState[K]>;
|
17
17
|
};
|
18
18
|
|
19
19
|
export type StorageStateChangedEvent<TState = any> = Diff<TState>;
|
20
20
|
|
21
|
-
export type StorageStateChangedListener<TState = any> = StorageEventListener<
|
21
|
+
export type StorageStateChangedListener<TState = any> = StorageEventListener<
|
22
|
+
StorageStateChangedEvent<TState>
|
23
|
+
>;
|
22
24
|
|
23
25
|
export type StorageStateChangedListenerDisposer = () => void;
|
package/src/App/Storage/utils.ts
CHANGED
@@ -5,13 +5,13 @@ import type { AutoRefValue, ExtractRawValue, RefValue } from "./typings";
|
|
5
5
|
export const plainObjectKeys = Object.keys as <T>(o: T) => Array<Extract<keyof T, string>>;
|
6
6
|
|
7
7
|
export function isRef<TValue = unknown>(e: unknown): e is RefValue<TValue> {
|
8
|
-
|
8
|
+
return Boolean(has(e, "__isRef"));
|
9
9
|
}
|
10
10
|
|
11
11
|
export function makeRef<TValue>(v: TValue): RefValue<TValue> {
|
12
|
-
|
12
|
+
return { k: genUID(), v, __isRef: true };
|
13
13
|
}
|
14
14
|
|
15
15
|
export function makeAutoRef<TValue>(v: TValue): AutoRefValue<TValue> {
|
16
|
-
|
16
|
+
return isRef<ExtractRawValue<TValue>>(v) ? v : makeRef(v as ExtractRawValue<TValue>);
|
17
17
|
}
|
package/src/AppListener.ts
CHANGED
@@ -11,7 +11,7 @@ type SetAppFocusIndex = {
|
|
11
11
|
type: "main" | "app";
|
12
12
|
appID?: string;
|
13
13
|
index: number;
|
14
|
-
}
|
14
|
+
};
|
15
15
|
|
16
16
|
export class AppListeners {
|
17
17
|
private displayer = this.manager.displayer;
|
@@ -121,15 +121,15 @@ export class AppListeners {
|
|
121
121
|
this.manager.createRootDirScenesCallback();
|
122
122
|
this.manager.mainViewProxy.rebind();
|
123
123
|
internalEmitter.emit("rootDirRemoved");
|
124
|
-
}
|
124
|
+
};
|
125
125
|
|
126
126
|
private refreshHandler = () => {
|
127
127
|
this.manager.windowManger._refresh();
|
128
|
-
}
|
128
|
+
};
|
129
129
|
|
130
130
|
private initMainViewCameraHandler = () => {
|
131
131
|
this.manager.mainViewProxy.addCameraReaction();
|
132
|
-
}
|
132
|
+
};
|
133
133
|
|
134
134
|
private setAppFocusViewIndexHandler = (payload: SetAppFocusIndex) => {
|
135
135
|
if (payload.type === "main") {
|
@@ -140,5 +140,5 @@ export class AppListeners {
|
|
140
140
|
app.setSceneIndexWithoutSync(payload.index);
|
141
141
|
}
|
142
142
|
}
|
143
|
-
}
|
143
|
+
};
|
144
144
|
}
|
@@ -38,14 +38,13 @@ export type StoreContext = {
|
|
38
38
|
getAttributes: () => any;
|
39
39
|
safeUpdateAttributes: (keys: string[], value: any) => void;
|
40
40
|
safeSetAttributes: (attributes: any) => void;
|
41
|
-
}
|
41
|
+
};
|
42
42
|
|
43
43
|
export type ICamera = Camera & { id: string };
|
44
44
|
|
45
45
|
export type ISize = Size & { id: string };
|
46
46
|
|
47
47
|
export class AttributesDelegate {
|
48
|
-
|
49
48
|
constructor(private context: StoreContext) {}
|
50
49
|
|
51
50
|
public setContext(context: StoreContext) {
|
@@ -181,7 +180,7 @@ export class AttributesDelegate {
|
|
181
180
|
} else {
|
182
181
|
this.context.safeSetAttributes({ [Fields.Focus]: undefined });
|
183
182
|
}
|
184
|
-
}
|
183
|
+
};
|
185
184
|
|
186
185
|
public updateCursor(uid: string, position: Position) {
|
187
186
|
if (!get(this.attributes, [Fields.Cursors])) {
|
@@ -250,15 +249,14 @@ export type Cursors = {
|
|
250
249
|
[key: string]: Cursor;
|
251
250
|
};
|
252
251
|
|
253
|
-
|
254
252
|
export const store = new AttributesDelegate({
|
255
253
|
getAttributes: () => {
|
256
|
-
throw new Error("getAttributes not implemented")
|
254
|
+
throw new Error("getAttributes not implemented");
|
257
255
|
},
|
258
256
|
safeSetAttributes: () => {
|
259
|
-
throw new Error("safeSetAttributes not implemented")
|
257
|
+
throw new Error("safeSetAttributes not implemented");
|
260
258
|
},
|
261
259
|
safeUpdateAttributes: () => {
|
262
|
-
throw new Error("safeUpdateAttributes not implemented")
|
260
|
+
throw new Error("safeUpdateAttributes not implemented");
|
263
261
|
},
|
264
262
|
});
|