@praxisjs/store 1.0.8 → 1.0.10
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 +24 -0
- 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 +3 -3
- 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,29 @@
|
|
|
1
1
|
# @praxisjs/store
|
|
2
2
|
|
|
3
|
+
## 1.0.10
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 9c7a165: fix: constrain `@State` and `@DeepState` to reactive classes only
|
|
8
|
+
|
|
9
|
+
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.
|
|
10
|
+
|
|
11
|
+
`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.
|
|
12
|
+
|
|
13
|
+
`@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.
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [9c7a165]
|
|
16
|
+
- @praxisjs/decorators@0.8.1
|
|
17
|
+
|
|
18
|
+
## 1.0.9
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- Updated dependencies [9affc5c]
|
|
23
|
+
- Updated dependencies [2f08576]
|
|
24
|
+
- @praxisjs/core@1.5.0
|
|
25
|
+
- @praxisjs/decorators@0.8.0
|
|
26
|
+
|
|
3
27
|
## 1.0.8
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
|
@@ -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.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"typescript": "^5.9.3"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@praxisjs/core": "1.
|
|
18
|
-
"@praxisjs/decorators": "0.
|
|
17
|
+
"@praxisjs/core": "1.5.0",
|
|
18
|
+
"@praxisjs/decorators": "0.8.1"
|
|
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";
|