cx 26.7.1 → 26.7.3

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.
@@ -1,226 +1,217 @@
1
- /** @jsxImportSource react */
2
- import { PureContainer, PureContainerBase, PureContainerConfig } from "./PureContainer";
3
- import { Store } from "../data/Store";
4
- import { View } from "../data/View";
5
- import { Cx } from "./Cx";
6
- import { VDOM } from "./VDOM";
7
- import { isObject } from "../util/isObject";
8
- import { isUndefined } from "../util/isUndefined";
9
- import { Binding } from "../data/Binding";
10
- import { StructuredSelector } from "../data/StructuredSelector";
11
- import { getCurrentCulture, CultureInfo } from "./Culture";
12
- import { BooleanProp, NumberProp, StringProp, StructuredProp } from "./Prop";
13
- import { Instance } from "./Instance";
14
-
15
- let persistenceCache: any = {};
16
-
17
- export interface RestateConfig extends PureContainerConfig {
18
- /** Data object to be exposed in the local store. */
19
- data?: StructuredProp;
20
-
21
- /** Set to `true` to render the content in a separate, detached rendering context. */
22
- detached?: boolean;
23
-
24
- /** Set to `true` to defer updates until the browser is idle. */
25
- deferredUntilIdle?: BooleanProp;
26
-
27
- /** Timeout in milliseconds for idle updates. */
28
- idleTimeout?: NumberProp;
29
-
30
- /** Key used to cache and persist the local store data. */
31
- cacheKey?: StringProp;
32
-
33
- /** Set to `true` to disable batching of updates. */
34
- immediate?: boolean;
35
-
36
- /** Cap re-entrant synchronous updates on the detached `Cx` this Restate renders: once a burst of
37
- * back-to-back updates gets too deep, defer the excess to the coalesced branch instead of updating
38
- * synchronously. Avoids React's "Maximum update depth exceeded" on very large synchronous render bursts.
39
- * Only applies in `detached` mode (a non-detached Restate has no `Cx` of its own). Off by default. */
40
- limitSyncBursts?: boolean;
41
-
42
- /** Error handler callback. */
43
- onError?: (error: Error, instance: Instance) => void;
44
-
45
- /** Culture info to be used for formatting. */
46
- culture?: CultureInfo;
47
- }
48
-
49
- // Legacy alias for backward compatibility
50
- export interface RestateProps extends RestateConfig {}
51
-
52
- export class Restate<Config extends RestateConfig = RestateConfig> extends PureContainerBase<Config> {
53
- declare container: any;
54
- declare privateDataSelector: any;
55
- declare detached: boolean;
56
- declare data?: any;
57
- declare culture?: any;
58
- declare options?: any;
59
- declare onError?: (error: Error, instance: Instance) => void;
60
- declare waitForIdle: boolean;
61
- declare immediate: boolean;
62
- declare limitSyncBursts: boolean;
63
-
64
- declareData(...args: any[]) {
65
- return super.declareData(...args, {
66
- deferredUntilIdle: undefined,
67
- idleTimeout: undefined,
68
- cacheKey: undefined,
69
- });
70
- }
71
-
72
- init() {
73
- this.container = PureContainer.create({
74
- items: this.children || this.items,
75
- layout: this.layout,
76
- controller: this.controller,
77
- outerLayout: this.outerLayout,
78
- useParentLayout: !this.detached,
79
- ws: this.ws,
80
- });
81
- this.privateDataSelector = new StructuredSelector({
82
- props: this.data || {},
83
- values: this.data,
84
- });
85
- this.items = [];
86
- delete this.children;
87
- delete this.controller;
88
- delete this.outerLayout;
89
- delete this.layout;
90
- if (this.useParentLayout == null) this.useParentLayout = !this.detached;
91
- super.init();
92
- }
93
-
94
- initSubStore(context: any, instance: any) {
95
- let { cacheKey } = instance.data;
96
- this.privateDataSelector.init(instance.store);
97
- instance.subStore = new RestateStore({
98
- store: instance.store,
99
- detached: this.detached,
100
- privateData: this.data || {},
101
- data: cacheKey ? persistenceCache[cacheKey] || {} : {},
102
- dataSelector: this.privateDataSelector.create(),
103
- onSet: (path: string, value: any) => instance.nestedDataSet(path, value, this.data),
104
- });
105
-
106
- if (cacheKey) {
107
- instance.subscribeOnDestroy(() => {
108
- persistenceCache[cacheKey] = instance.subStore.getData();
109
- });
110
- }
111
- }
112
-
113
- applyParentStore(instance: any) {
114
- if (instance.subStore) instance.subStore.setStore(instance.parentStore);
115
- }
116
-
117
- explore(context: any, instance: any) {
118
- if (!instance.subStore) this.initSubStore(context, instance);
119
- if (instance.subStore.parentDataCheck()) instance.markShouldUpdate();
120
- instance.cultureInfo = this.culture ?? getCurrentCulture();
121
- if (instance.cache("cultureInfo", instance.culture)) instance.markShouldUpdate();
122
- super.explore(context, instance);
123
- }
124
-
125
- exploreItems(context: any, instance: any, items: any) {
126
- if (!this.detached) {
127
- instance.container = instance.getChild(context, this.container, "container", instance.subStore);
128
- instance.container.scheduleExploreIfVisible(context);
129
- instance.children = [instance.container];
130
- }
131
- }
132
-
133
- render(context: any, instance: any, key: string) {
134
- if (!this.detached) return instance.container.render(context);
135
-
136
- return (
137
- <Cx
138
- key={key}
139
- widget={this.container}
140
- parentInstance={instance}
141
- store={instance.subStore}
142
- subscribe
143
- options={this.options}
144
- onError={this.onError}
145
- deferredUntilIdle={instance.data.deferredUntilIdle}
146
- idleTimeout={instance.data.idleTimeout}
147
- immediate={this.immediate}
148
- limitSyncBursts={this.limitSyncBursts}
149
- cultureInfo={instance.cultureInfo}
150
- />
151
- );
152
- }
153
- }
154
-
155
- Restate.prototype.detached = false;
156
- Restate.prototype.waitForIdle = false;
157
- Restate.prototype.immediate = false;
158
- Restate.prototype.limitSyncBursts = false;
159
- Restate.prototype.culture = null;
160
-
161
- export const PrivateStore = Restate;
162
-
163
- class RestateStore extends Store {
164
- declare parentDataVersion: number;
165
- declare parentData: any;
166
- declare dataSelector: any;
167
- declare privateData: any;
168
- declare onSet: any;
169
- declare detached: any;
170
- declare store: View; // Parent store reference
171
-
172
- constructor(config: any) {
173
- super(config);
174
- this.parentDataVersion = -1;
175
- }
176
-
177
- getData() {
178
- this.silently(() => {
179
- this.parentDataCheck();
180
- });
181
- return super.getData();
182
- }
183
-
184
- parentDataCheck() {
185
- if (this.parentDataVersion == this.store.meta.version) return false;
186
- this.parentDataVersion = this.store.meta.version;
187
- this.parentData = this.dataSelector(this.store.getData());
188
- return this.batch(() => {
189
- for (let key in this.parentData) {
190
- super.setItem(key, this.parentData[key]);
191
- }
192
- });
193
- }
194
-
195
- setItem(path: string, value: any) {
196
- let binding = Binding.get(path);
197
- let bindingRoot = binding.parts[0];
198
- if (!isObject(this.privateData) || !this.privateData.hasOwnProperty(bindingRoot)) {
199
- let changed = isUndefined(value) ? super.deleteItem(path) : super.setItem(path, value);
200
- return changed;
201
- }
202
-
203
- let newValue = value;
204
- if (binding.parts.length > 1) newValue = binding.set(this.getData(), value)[bindingRoot];
205
- this.onSet(bindingRoot, newValue);
206
- this.batch(() => {
207
- super.setItem(bindingRoot, newValue);
208
- this.parentDataCheck();
209
- });
210
- return true;
211
- }
212
-
213
- deleteItem(path: string) {
214
- return this.setItem(path, undefined);
215
- }
216
-
217
- doNotify() {
218
- if (!this.detached) this.store.notify(undefined!);
219
- super.doNotify(undefined!);
220
- }
221
-
222
- // override the default implementation to avoid meta overwrites
223
- setStore(store: any) {
224
- this.store = store;
225
- }
226
- }
1
+ /** @jsxImportSource react */
2
+ import { PureContainer, PureContainerBase, PureContainerConfig } from "./PureContainer";
3
+ import { Store } from "../data/Store";
4
+ import { View } from "../data/View";
5
+ import { Cx } from "./Cx";
6
+ import { VDOM } from "./VDOM";
7
+ import { isObject } from "../util/isObject";
8
+ import { isUndefined } from "../util/isUndefined";
9
+ import { Binding } from "../data/Binding";
10
+ import { StructuredSelector } from "../data/StructuredSelector";
11
+ import { getCurrentCulture, CultureInfo } from "./Culture";
12
+ import { BooleanProp, NumberProp, StringProp, StructuredProp } from "./Prop";
13
+ import { Instance } from "./Instance";
14
+
15
+ let persistenceCache: any = {};
16
+
17
+ export interface RestateConfig extends PureContainerConfig {
18
+ /** Data object to be exposed in the local store. */
19
+ data?: StructuredProp;
20
+
21
+ /** Set to `true` to render the content in a separate, detached rendering context. */
22
+ detached?: boolean;
23
+
24
+ /** Set to `true` to defer updates until the browser is idle. */
25
+ deferredUntilIdle?: BooleanProp;
26
+
27
+ /** Timeout in milliseconds for idle updates. */
28
+ idleTimeout?: NumberProp;
29
+
30
+ /** Key used to cache and persist the local store data. */
31
+ cacheKey?: StringProp;
32
+
33
+ /** Set to `true` to disable batching of updates. */
34
+ immediate?: boolean;
35
+
36
+ /** Error handler callback. */
37
+ onError?: (error: Error, instance: Instance) => void;
38
+
39
+ /** Culture info to be used for formatting. */
40
+ culture?: CultureInfo;
41
+ }
42
+
43
+ // Legacy alias for backward compatibility
44
+ export interface RestateProps extends RestateConfig {}
45
+
46
+ export class Restate<Config extends RestateConfig = RestateConfig> extends PureContainerBase<Config> {
47
+ declare container: any;
48
+ declare privateDataSelector: any;
49
+ declare detached: boolean;
50
+ declare data?: any;
51
+ declare culture?: any;
52
+ declare options?: any;
53
+ declare onError?: (error: Error, instance: Instance) => void;
54
+ declare waitForIdle: boolean;
55
+ declare immediate: boolean;
56
+
57
+ declareData(...args: any[]) {
58
+ return super.declareData(...args, {
59
+ deferredUntilIdle: undefined,
60
+ idleTimeout: undefined,
61
+ cacheKey: undefined,
62
+ });
63
+ }
64
+
65
+ init() {
66
+ this.container = PureContainer.create({
67
+ items: this.children || this.items,
68
+ layout: this.layout,
69
+ controller: this.controller,
70
+ outerLayout: this.outerLayout,
71
+ useParentLayout: !this.detached,
72
+ ws: this.ws,
73
+ });
74
+ this.privateDataSelector = new StructuredSelector({
75
+ props: this.data || {},
76
+ values: this.data,
77
+ });
78
+ this.items = [];
79
+ delete this.children;
80
+ delete this.controller;
81
+ delete this.outerLayout;
82
+ delete this.layout;
83
+ if (this.useParentLayout == null) this.useParentLayout = !this.detached;
84
+ super.init();
85
+ }
86
+
87
+ initSubStore(context: any, instance: any) {
88
+ let { cacheKey } = instance.data;
89
+ this.privateDataSelector.init(instance.store);
90
+ instance.subStore = new RestateStore({
91
+ store: instance.store,
92
+ detached: this.detached,
93
+ privateData: this.data || {},
94
+ data: cacheKey ? persistenceCache[cacheKey] || {} : {},
95
+ dataSelector: this.privateDataSelector.create(),
96
+ onSet: (path: string, value: any) => instance.nestedDataSet(path, value, this.data),
97
+ });
98
+
99
+ if (cacheKey) {
100
+ instance.subscribeOnDestroy(() => {
101
+ persistenceCache[cacheKey] = instance.subStore.getData();
102
+ });
103
+ }
104
+ }
105
+
106
+ applyParentStore(instance: any) {
107
+ if (instance.subStore) instance.subStore.setStore(instance.parentStore);
108
+ }
109
+
110
+ explore(context: any, instance: any) {
111
+ if (!instance.subStore) this.initSubStore(context, instance);
112
+ if (instance.subStore.parentDataCheck()) instance.markShouldUpdate();
113
+ instance.cultureInfo = this.culture ?? getCurrentCulture();
114
+ if (instance.cache("cultureInfo", instance.culture)) instance.markShouldUpdate();
115
+ super.explore(context, instance);
116
+ }
117
+
118
+ exploreItems(context: any, instance: any, items: any) {
119
+ if (!this.detached) {
120
+ instance.container = instance.getChild(context, this.container, "container", instance.subStore);
121
+ instance.container.scheduleExploreIfVisible(context);
122
+ instance.children = [instance.container];
123
+ }
124
+ }
125
+
126
+ render(context: any, instance: any, key: string) {
127
+ if (!this.detached) return instance.container.render(context);
128
+
129
+ return (
130
+ <Cx
131
+ key={key}
132
+ widget={this.container}
133
+ parentInstance={instance}
134
+ store={instance.subStore}
135
+ subscribe
136
+ options={this.options}
137
+ onError={this.onError}
138
+ deferredUntilIdle={instance.data.deferredUntilIdle}
139
+ idleTimeout={instance.data.idleTimeout}
140
+ immediate={this.immediate}
141
+ cultureInfo={instance.cultureInfo}
142
+ />
143
+ );
144
+ }
145
+ }
146
+
147
+ Restate.prototype.detached = false;
148
+ Restate.prototype.waitForIdle = false;
149
+ Restate.prototype.immediate = false;
150
+ Restate.prototype.culture = null;
151
+
152
+ export const PrivateStore = Restate;
153
+
154
+ class RestateStore extends Store {
155
+ declare parentDataVersion: number;
156
+ declare parentData: any;
157
+ declare dataSelector: any;
158
+ declare privateData: any;
159
+ declare onSet: any;
160
+ declare detached: any;
161
+ declare store: View; // Parent store reference
162
+
163
+ constructor(config: any) {
164
+ super(config);
165
+ this.parentDataVersion = -1;
166
+ }
167
+
168
+ getData() {
169
+ this.silently(() => {
170
+ this.parentDataCheck();
171
+ });
172
+ return super.getData();
173
+ }
174
+
175
+ parentDataCheck() {
176
+ if (this.parentDataVersion == this.store.meta.version) return false;
177
+ this.parentDataVersion = this.store.meta.version;
178
+ this.parentData = this.dataSelector(this.store.getData());
179
+ return this.batch(() => {
180
+ for (let key in this.parentData) {
181
+ super.setItem(key, this.parentData[key]);
182
+ }
183
+ });
184
+ }
185
+
186
+ setItem(path: string, value: any) {
187
+ let binding = Binding.get(path);
188
+ let bindingRoot = binding.parts[0];
189
+ if (!isObject(this.privateData) || !this.privateData.hasOwnProperty(bindingRoot)) {
190
+ let changed = isUndefined(value) ? super.deleteItem(path) : super.setItem(path, value);
191
+ return changed;
192
+ }
193
+
194
+ let newValue = value;
195
+ if (binding.parts.length > 1) newValue = binding.set(this.getData(), value)[bindingRoot];
196
+ this.onSet(bindingRoot, newValue);
197
+ this.batch(() => {
198
+ super.setItem(bindingRoot, newValue);
199
+ this.parentDataCheck();
200
+ });
201
+ return true;
202
+ }
203
+
204
+ deleteItem(path: string) {
205
+ return this.setItem(path, undefined);
206
+ }
207
+
208
+ doNotify() {
209
+ if (!this.detached) this.store.notify(undefined!);
210
+ super.doNotify(undefined!);
211
+ }
212
+
213
+ // override the default implementation to avoid meta overwrites
214
+ setStore(store: any) {
215
+ this.store = store;
216
+ }
217
+ }