@praxisjs/store 1.0.9 → 1.0.11
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 +25 -9
- package/dist/__tests__/decorators.test.js +19 -13
- package/dist/__tests__/decorators.test.js.map +1 -1
- package/dist/decorators.d.ts +6 -1
- package/dist/decorators.d.ts.map +1 -1
- package/dist/decorators.js +8 -13
- package/dist/decorators.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/decorators.test.ts +13 -13
- package/src/decorators.ts +10 -20
- package/src/index.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @praxisjs/store
|
|
2
2
|
|
|
3
|
+
## 1.0.11
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [954e456]
|
|
8
|
+
- Updated dependencies [a0bf339]
|
|
9
|
+
- Updated dependencies [a0bf339]
|
|
10
|
+
- Updated dependencies [a8df1e1]
|
|
11
|
+
- @praxisjs/decorators@1.0.0
|
|
12
|
+
|
|
13
|
+
## 1.0.10
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 9c7a165: fix: constrain `@State` and `@DeepState` to reactive classes only
|
|
18
|
+
|
|
19
|
+
Introduces `ReactiveHost` (`{ _stateDirty: boolean }`) exported from `@praxisjs/decorators`. `@State` and `@DeepState` now use `createFieldDecorator<ReactiveHost>` with a generic `<This extends ReactiveHost, Value>` constraint, producing a TS error when applied to plain classes.
|
|
20
|
+
|
|
21
|
+
`createFieldDecorator` now returns a generic function `<This extends T, Value>` so TypeScript infers the actual class type at the call site and checks the constraint against it instead of doing a fixed structural check.
|
|
22
|
+
|
|
23
|
+
`@Store` is simplified to a plain class decorator (no longer uses `createClassDecorator`). A new `ReactiveStore` base class is exported from `@praxisjs/store` — store classes must extend it to satisfy the `ReactiveHost` constraint required by `@State` and `@DeepState`. Template updated accordingly.
|
|
24
|
+
|
|
25
|
+
- Updated dependencies [9c7a165]
|
|
26
|
+
- @praxisjs/decorators@0.8.1
|
|
27
|
+
|
|
3
28
|
## 1.0.9
|
|
4
29
|
|
|
5
30
|
### Patch Changes
|
|
@@ -82,39 +107,31 @@
|
|
|
82
107
|
- 3372878: Migrate all packages from functional APIs to a decorator-first design.
|
|
83
108
|
|
|
84
109
|
**`@praxisjs/core`**
|
|
85
|
-
|
|
86
110
|
- Added `Composable` abstract base class for building class-based composables
|
|
87
111
|
- Removed `resource`, `createResource`, `Resource`, `ResourceStatus`, `ResourceOptions` from public exports — use `@Resource` from `@praxisjs/decorators` instead
|
|
88
112
|
|
|
89
113
|
**`@praxisjs/motion`**
|
|
90
|
-
|
|
91
114
|
- Replaced `useMotion`, `tween`, `spring`, `createTransition`, `Animate`, `easings`, `resolveEasing` with `@Tween` and `@Spring` decorators
|
|
92
115
|
|
|
93
116
|
**`@praxisjs/di`**
|
|
94
|
-
|
|
95
117
|
- Replaced `useService` and `createScope` with a `@Scope` decorator
|
|
96
118
|
- Renamed exported type `Scope` to `ScopeType` to free the name for the new decorator
|
|
97
119
|
|
|
98
120
|
**`@praxisjs/fsm`**
|
|
99
|
-
|
|
100
121
|
- Removed `createMachine` — use the `@StateMachine` and `@Transition` decorators directly
|
|
101
122
|
|
|
102
123
|
**`@praxisjs/router`**
|
|
103
|
-
|
|
104
124
|
- Removed `createRouter`, `lazy`, `useRouter`, `useParams`, `useQuery`, `useLocation`
|
|
105
125
|
- Added `@RouterConfig`, `@Lazy`, `@InjectRouter`, `@Params`, `@Query`, `@Location` decorators
|
|
106
126
|
|
|
107
127
|
**`@praxisjs/store`**
|
|
108
|
-
|
|
109
128
|
- Removed `createStore` — use the `@Store` and `@UseStore` decorators directly
|
|
110
129
|
|
|
111
130
|
**`@praxisjs/composables`**
|
|
112
|
-
|
|
113
131
|
- Replaced all `use*` composable functions with class-based composables extending `Composable`:
|
|
114
132
|
`WindowSize`, `ScrollPosition`, `ElementSize`, `Intersection`, `Focus`, `MediaQuery`, `ColorScheme`, `Mouse`, `KeyCombo`, `Idle`, `Clipboard`, `Geolocation`, `TimeAgo`, `Pagination`
|
|
115
133
|
|
|
116
134
|
**`@praxisjs/concurrent`**
|
|
117
|
-
|
|
118
135
|
- Removed `task`, `queue`, `pool` and their instance types — use `@Task`, `@Queue`, `@Pool` decorators instead
|
|
119
136
|
|
|
120
137
|
### Patch Changes
|
|
@@ -156,7 +173,6 @@
|
|
|
156
173
|
### Minor Changes
|
|
157
174
|
|
|
158
175
|
- bb0d4f8: **Refactor decorator system and component architecture across PraxisJS packages**
|
|
159
|
-
|
|
160
176
|
- Replaced legacy decorator signatures (`constructor`, `target`, `propertyKey`, method descriptor) with the standard TC39 decorator context API (`ClassDecoratorContext`, `ClassFieldDecoratorContext`, `ClassMethodDecoratorContext`) across `@praxisjs/decorators`, `@praxisjs/store`, `@praxisjs/concurrent`, `@praxisjs/router`, `@praxisjs/motion`, `@praxisjs/di`, and `@praxisjs/fsm`.
|
|
161
177
|
- Introduced `StatefulComponent` and `StatelessComponent` as the new base classes, replacing the deprecated `BaseComponent`/`Function Component` pattern, across `@praxisjs/core`, `@praxisjs/runtime`, `@praxisjs/devtools`, and templates.
|
|
162
178
|
- Implemented core rendering functionality in `@praxisjs/runtime` (`mountChildren`, `mountComponent`, reactive scope management) and removed the deprecated `renderer.ts`.
|
|
@@ -1,25 +1,27 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { Store, UseStore } from "../decorators";
|
|
2
|
+
import { Store, UseStore, ReactiveStore } from "../decorators";
|
|
3
3
|
describe("Store decorator", () => {
|
|
4
4
|
it("registers the class without throwing", () => {
|
|
5
|
-
class CounterStore {
|
|
5
|
+
class CounterStore extends ReactiveStore {
|
|
6
6
|
constructor() {
|
|
7
|
+
super(...arguments);
|
|
7
8
|
this.value = 0;
|
|
8
9
|
}
|
|
9
10
|
}
|
|
10
11
|
expect(() => { Store()(CounterStore, {}); }).not.toThrow();
|
|
11
12
|
});
|
|
12
|
-
it("
|
|
13
|
-
class MyStore {
|
|
13
|
+
it("returns void and the original class remains directly instantiable", () => {
|
|
14
|
+
class MyStore extends ReactiveStore {
|
|
14
15
|
constructor() {
|
|
16
|
+
super(...arguments);
|
|
15
17
|
this.value = 42;
|
|
16
18
|
}
|
|
17
19
|
}
|
|
18
20
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
expect(
|
|
21
|
+
const result = Store()(MyStore, {});
|
|
22
|
+
expect(result).toBeUndefined();
|
|
23
|
+
expect(() => new MyStore()).not.toThrow();
|
|
24
|
+
expect(new MyStore().value).toBe(42);
|
|
23
25
|
});
|
|
24
26
|
});
|
|
25
27
|
function makeFieldCtx(name) {
|
|
@@ -35,8 +37,9 @@ function makeFieldCtx(name) {
|
|
|
35
37
|
}
|
|
36
38
|
describe("UseStore decorator", () => {
|
|
37
39
|
it("injects a singleton store instance via getter", () => {
|
|
38
|
-
class AppStore {
|
|
40
|
+
class AppStore extends ReactiveStore {
|
|
39
41
|
constructor() {
|
|
42
|
+
super(...arguments);
|
|
40
43
|
this.name = "app";
|
|
41
44
|
}
|
|
42
45
|
}
|
|
@@ -49,7 +52,7 @@ describe("UseStore decorator", () => {
|
|
|
49
52
|
expect(instance.store.name).toBe("app");
|
|
50
53
|
});
|
|
51
54
|
it("returns the same instance on repeated access (singleton)", () => {
|
|
52
|
-
class SharedStore {
|
|
55
|
+
class SharedStore extends ReactiveStore {
|
|
53
56
|
}
|
|
54
57
|
Store()(SharedStore, {});
|
|
55
58
|
const { ctx, run } = makeFieldCtx("sharedStore");
|
|
@@ -75,13 +78,15 @@ describe("UseStore decorator", () => {
|
|
|
75
78
|
expect(instance.svc).toBeInstanceOf(NotRegistered);
|
|
76
79
|
});
|
|
77
80
|
it("@UseStore on two fields of same class — each field gets the correct store type independently", () => {
|
|
78
|
-
class StoreAlpha {
|
|
81
|
+
class StoreAlpha extends ReactiveStore {
|
|
79
82
|
constructor() {
|
|
83
|
+
super(...arguments);
|
|
80
84
|
this.kind = "alpha";
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
|
-
class StoreBeta {
|
|
87
|
+
class StoreBeta extends ReactiveStore {
|
|
84
88
|
constructor() {
|
|
89
|
+
super(...arguments);
|
|
85
90
|
this.kind = "beta";
|
|
86
91
|
}
|
|
87
92
|
}
|
|
@@ -100,8 +105,9 @@ describe("UseStore decorator", () => {
|
|
|
100
105
|
expect(instance.beta.kind).toBe("beta");
|
|
101
106
|
});
|
|
102
107
|
it("store singleton is shared across multiple class instances", () => {
|
|
103
|
-
class CounterStore {
|
|
108
|
+
class CounterStore extends ReactiveStore {
|
|
104
109
|
constructor() {
|
|
110
|
+
super(...arguments);
|
|
105
111
|
this.count = 0;
|
|
106
112
|
}
|
|
107
113
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorators.test.js","sourceRoot":"","sources":["../../src/__tests__/decorators.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"decorators.test.js","sourceRoot":"","sources":["../../src/__tests__/decorators.test.ts"],"names":[],"mappings":"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"}
|
package/dist/decorators.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { type ReactiveHost } from "@praxisjs/decorators";
|
|
2
|
+
/** Base class for store classes. Extend this to enable `@State` and `@DeepState` on store fields. */
|
|
3
|
+
export declare class ReactiveStore implements ReactiveHost {
|
|
4
|
+
_stateDirty: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function Store(): (constructor: new (...args: unknown[]) => ReactiveStore, _context: ClassDecoratorContext) => void;
|
|
2
7
|
export declare function UseStore(StoreConstructor: new () => unknown): (_value: undefined, context: ClassFieldDecoratorContext<any>) => void;
|
|
3
8
|
//# sourceMappingURL=decorators.d.ts.map
|
package/dist/decorators.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAI9B,qGAAqG;AACrG,qBAAa,aAAc,YAAW,YAAY;IAChD,WAAW,UAAS;CACrB;AAED,wBAAgB,KAAK,KAEjB,aAAa,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,aAAa,EACtD,UAAU,qBAAqB,KAC9B,IAAI,CAGR;AAED,wBAAgB,QAAQ,CAAC,gBAAgB,EAAE,UAAU,OAAO,GAuBzC,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,0BAA0B,CAAC,GAAG,CAAC,KAAK,IAAI,CACvF"}
|
package/dist/decorators.js
CHANGED
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createFieldDecorator, } from "@praxisjs/decorators";
|
|
2
2
|
const storeRegistry = new Map();
|
|
3
|
-
class
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
|
-
initialize(Enhanced) {
|
|
9
|
-
storeRegistry.set(Enhanced, null);
|
|
3
|
+
/** Base class for store classes. Extend this to enable `@State` and `@DeepState` on store fields. */
|
|
4
|
+
export class ReactiveStore {
|
|
5
|
+
constructor() {
|
|
6
|
+
this._stateDirty = false;
|
|
10
7
|
}
|
|
11
8
|
}
|
|
12
|
-
const storeBehavior = new StoreBehavior();
|
|
13
9
|
export function Store() {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
return function (constructor, _context) {
|
|
11
|
+
storeRegistry.set(constructor, null);
|
|
12
|
+
};
|
|
17
13
|
}
|
|
18
14
|
export function UseStore(StoreConstructor) {
|
|
19
15
|
const cache = new WeakMap();
|
|
@@ -34,7 +30,6 @@ export function UseStore(StoreConstructor) {
|
|
|
34
30
|
},
|
|
35
31
|
};
|
|
36
32
|
},
|
|
37
|
-
// Store decorators work on any class, not just StatefulComponent
|
|
38
33
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
39
34
|
});
|
|
40
35
|
}
|
package/dist/decorators.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorators.js","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"decorators.js","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,GAGrB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,aAAa,GAAG,IAAI,GAAG,EAAgD,CAAC;AAE9E,qGAAqG;AACrG,MAAM,OAAO,aAAa;IAA1B;QACE,gBAAW,GAAG,KAAK,CAAC;IACtB,CAAC;CAAA;AAED,MAAM,UAAU,KAAK;IACnB,OAAO,UACL,WAAsD,EACtD,QAA+B;QAE/B,aAAa,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,gBAAmC;IAC1D,MAAM,KAAK,GAAG,IAAI,OAAO,EAAmB,CAAC;IAE7C,OAAO,oBAAoB,CAAC;QAC1B,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,aAAa;YAClC,OAAO;gBACL,UAAU,EAAE;oBACV,GAAG;wBACD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;4BACrB,IACE,CAAC,aAAa,CAAC,GAAG,CAAC,gBAAgB,CAAC;gCACpC,aAAa,CAAC,GAAG,CAAC,gBAAgB,CAAC,KAAK,IAAI,EAC5C,CAAC;gCACD,aAAa,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,gBAAgB,EAAE,CAAC,CAAC;4BAC9D,CAAC;4BACD,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,aAAa,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC;wBACvD,CAAC;wBACD,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBACzB,CAAC;iBACF;aACF,CAAC;QACJ,CAAC;QACH,8DAA8D;KAC7D,CAAqF,CAAC;AACzF,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { Store, UseStore } from "./decorators";
|
|
1
|
+
export { Store, UseStore, ReactiveStore } from "./decorators";
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { Store, UseStore } from "./decorators";
|
|
1
|
+
export { Store, UseStore, ReactiveStore } from "./decorators";
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisjs/store",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@praxisjs/core": "1.5.0",
|
|
18
|
-
"@praxisjs/decorators": "0.
|
|
18
|
+
"@praxisjs/decorators": "1.0.0"
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|
|
21
21
|
"build": "tsc",
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
2
|
|
|
3
|
-
import { Store, UseStore } from "../decorators";
|
|
3
|
+
import { Store, UseStore, ReactiveStore } from "../decorators";
|
|
4
4
|
|
|
5
5
|
describe("Store decorator", () => {
|
|
6
6
|
it("registers the class without throwing", () => {
|
|
7
|
-
class CounterStore {
|
|
7
|
+
class CounterStore extends ReactiveStore {
|
|
8
8
|
value = 0;
|
|
9
9
|
}
|
|
10
10
|
expect(() =>
|
|
@@ -12,15 +12,15 @@ describe("Store decorator", () => {
|
|
|
12
12
|
).not.toThrow();
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
it("
|
|
16
|
-
class MyStore {
|
|
15
|
+
it("returns void and the original class remains directly instantiable", () => {
|
|
16
|
+
class MyStore extends ReactiveStore {
|
|
17
17
|
value = 42;
|
|
18
18
|
}
|
|
19
19
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
expect(
|
|
20
|
+
const result = Store()(MyStore as any, {} as ClassDecoratorContext);
|
|
21
|
+
expect(result).toBeUndefined();
|
|
22
|
+
expect(() => new MyStore()).not.toThrow();
|
|
23
|
+
expect(new MyStore().value).toBe(42);
|
|
24
24
|
});
|
|
25
25
|
});
|
|
26
26
|
|
|
@@ -38,7 +38,7 @@ function makeFieldCtx(name: string) {
|
|
|
38
38
|
|
|
39
39
|
describe("UseStore decorator", () => {
|
|
40
40
|
it("injects a singleton store instance via getter", () => {
|
|
41
|
-
class AppStore {
|
|
41
|
+
class AppStore extends ReactiveStore {
|
|
42
42
|
name = "app";
|
|
43
43
|
}
|
|
44
44
|
Store()(AppStore, {} as ClassDecoratorContext);
|
|
@@ -54,7 +54,7 @@ describe("UseStore decorator", () => {
|
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
it("returns the same instance on repeated access (singleton)", () => {
|
|
57
|
-
class SharedStore {}
|
|
57
|
+
class SharedStore extends ReactiveStore {}
|
|
58
58
|
Store()(SharedStore, {} as ClassDecoratorContext);
|
|
59
59
|
|
|
60
60
|
const { ctx, run } = makeFieldCtx("sharedStore");
|
|
@@ -82,10 +82,10 @@ describe("UseStore decorator", () => {
|
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
it("@UseStore on two fields of same class — each field gets the correct store type independently", () => {
|
|
85
|
-
class StoreAlpha {
|
|
85
|
+
class StoreAlpha extends ReactiveStore {
|
|
86
86
|
kind = "alpha";
|
|
87
87
|
}
|
|
88
|
-
class StoreBeta {
|
|
88
|
+
class StoreBeta extends ReactiveStore {
|
|
89
89
|
kind = "beta";
|
|
90
90
|
}
|
|
91
91
|
Store()(StoreAlpha, {} as ClassDecoratorContext);
|
|
@@ -107,7 +107,7 @@ describe("UseStore decorator", () => {
|
|
|
107
107
|
});
|
|
108
108
|
|
|
109
109
|
it("store singleton is shared across multiple class instances", () => {
|
|
110
|
-
class CounterStore {
|
|
110
|
+
class CounterStore extends ReactiveStore {
|
|
111
111
|
count = 0;
|
|
112
112
|
}
|
|
113
113
|
Store()(CounterStore, {} as ClassDecoratorContext);
|
package/src/decorators.ts
CHANGED
|
@@ -1,32 +1,23 @@
|
|
|
1
|
-
import type { RootComponent } from "@praxisjs/core/internal";
|
|
2
1
|
import {
|
|
3
|
-
createClassDecorator,
|
|
4
|
-
ClassBehavior,
|
|
5
|
-
type ClassEnhancement,
|
|
6
2
|
createFieldDecorator,
|
|
7
3
|
type FieldBinding,
|
|
4
|
+
type ReactiveHost,
|
|
8
5
|
} from "@praxisjs/decorators";
|
|
9
6
|
|
|
10
7
|
const storeRegistry = new Map<new (...args: unknown[]) => unknown, unknown>();
|
|
11
8
|
|
|
12
|
-
class
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
18
|
-
initialize(Enhanced: new (...args: any[]) => unknown): void {
|
|
19
|
-
storeRegistry.set(Enhanced as new (...args: unknown[]) => unknown, null);
|
|
20
|
-
}
|
|
9
|
+
/** Base class for store classes. Extend this to enable `@State` and `@DeepState` on store fields. */
|
|
10
|
+
export class ReactiveStore implements ReactiveHost {
|
|
11
|
+
_stateDirty = false;
|
|
21
12
|
}
|
|
22
13
|
|
|
23
|
-
const storeBehavior = new StoreBehavior();
|
|
24
|
-
|
|
25
14
|
export function Store() {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
15
|
+
return function (
|
|
16
|
+
constructor: new (...args: unknown[]) => ReactiveStore,
|
|
17
|
+
_context: ClassDecoratorContext,
|
|
18
|
+
): void {
|
|
19
|
+
storeRegistry.set(constructor, null);
|
|
20
|
+
};
|
|
30
21
|
}
|
|
31
22
|
|
|
32
23
|
export function UseStore(StoreConstructor: new () => unknown) {
|
|
@@ -51,7 +42,6 @@ export function UseStore(StoreConstructor: new () => unknown) {
|
|
|
51
42
|
},
|
|
52
43
|
};
|
|
53
44
|
},
|
|
54
|
-
// Store decorators work on any class, not just StatefulComponent
|
|
55
45
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
56
46
|
}) as unknown as (_value: undefined, context: ClassFieldDecoratorContext<any>) => void;
|
|
57
47
|
}
|
package/src/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { Store, UseStore } from "./decorators";
|
|
1
|
+
export { Store, UseStore, ReactiveStore } from "./decorators";
|