@praxisjs/core 1.8.2 → 2.0.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/CHANGELOG.md +27 -0
- package/dist/__tests__/component.test.js +59 -26
- package/dist/__tests__/component.test.js.map +1 -1
- package/dist/component/base.d.ts +2 -21
- package/dist/component/base.d.ts.map +1 -1
- package/dist/component/base.js +2 -24
- package/dist/component/base.js.map +1 -1
- package/dist/component/internals.d.ts +16 -0
- package/dist/component/internals.d.ts.map +1 -0
- package/dist/component/internals.js +70 -0
- package/dist/component/internals.js.map +1 -0
- package/dist/component/stateful.d.ts +0 -10
- package/dist/component/stateful.d.ts.map +1 -1
- package/dist/component/stateful.js +0 -13
- package/dist/component/stateful.js.map +1 -1
- package/dist/component/stateless.d.ts +2 -0
- package/dist/component/stateless.d.ts.map +1 -1
- package/dist/component/stateless.js +5 -0
- package/dist/component/stateless.js.map +1 -1
- package/dist/internal.d.ts +1 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -0
- package/dist/internal.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/component.test.ts +83 -26
- package/src/component/base.ts +4 -33
- package/src/component/internals.ts +119 -0
- package/src/component/stateful.ts +1 -14
- package/src/component/stateless.ts +5 -0
- package/src/internal.ts +16 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @praxisjs/core
|
|
2
2
|
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 8ab6426: Move component runtime state out of public instances and behind internal helpers.
|
|
8
|
+
|
|
9
|
+
BREAKING CHANGE: `RootComponent`, `StatefulComponent`, and `ReactiveStore` no longer expose framework-only underscore internals or `StatefulComponent.props` as public instance API.
|
|
10
|
+
|
|
11
|
+
`RootComponent` and `StatefulComponent` no longer expose framework-only underscore fields such as `_rawProps`, `_mounted`, `_anchor`, `_setProps`, `_defaults`, or `_stateDirty`. The renderer, decorators, JSX types, and first-party CSS utilities now use helpers from `@praxisjs/core/internal` to access that state.
|
|
12
|
+
|
|
13
|
+
For app code, `StatefulComponent` props should continue to be modeled with `@Prop()` fields. `StatelessComponent<T>` keeps its public `props` getter.
|
|
14
|
+
|
|
15
|
+
This also clarifies the intended props API: `StatelessComponent.props` is public, while `StatefulComponent` subclasses should read parent-provided values through `@Prop()` fields instead of `props`.
|
|
16
|
+
|
|
17
|
+
`ReactiveStore` now uses a type-only reactive-host marker for `@State`/`@DeepState` compatibility and no longer creates `_stateDirty` on store instances.
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Updated dependencies [8ab6426]
|
|
22
|
+
- @praxisjs/shared@0.3.1
|
|
23
|
+
|
|
24
|
+
## 1.8.3
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- 7d87288: Document `props` as `StatelessComponent`'s intended public API, and as an internal implementation detail on `StatefulComponent` (use `@Prop()` fields instead). No behavior change — `RootComponent.props`, `StatefulComponent.props`, and `StatelessComponent.props` all still return `_rawProps` exactly as before; this only clarifies, via JSDoc, which class each usage pattern is meant for.
|
|
29
|
+
|
|
3
30
|
## 1.8.2
|
|
4
31
|
|
|
5
32
|
### Patch Changes
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
2
|
import { RootComponent } from "../component/base";
|
|
3
|
+
import { getComponentAnchor, getComponentDefault, getComponentDefaults, getComponentProps, getComponentRawProp, isComponentMounted, isStateDirty, markStateDirty, setComponentAnchor, setComponentDefault, setComponentMounted, setComponentProps, setStateDirty, } from "../component/internals";
|
|
3
4
|
import { StatefulComponent } from "../component/stateful";
|
|
4
5
|
import { StatelessComponent } from "../component/stateless";
|
|
5
6
|
class ConcreteRoot extends RootComponent {
|
|
@@ -13,41 +14,73 @@ class ConcreteStateful extends StatefulComponent {
|
|
|
13
14
|
}
|
|
14
15
|
}
|
|
15
16
|
describe("RootComponent", () => {
|
|
16
|
-
it("stores props
|
|
17
|
+
it("stores props in component internals", () => {
|
|
17
18
|
const c = new ConcreteRoot({ name: "Alice" });
|
|
18
|
-
expect(c.
|
|
19
|
+
expect(getComponentProps(c).name).toBe("Alice");
|
|
19
20
|
});
|
|
20
|
-
it("
|
|
21
|
-
const c = new ConcreteRoot({ name: "
|
|
22
|
-
expect(
|
|
21
|
+
it("does not expose old underscore internals as own properties", () => {
|
|
22
|
+
const c = new ConcreteRoot({ name: "Alice" });
|
|
23
|
+
expect(Object.prototype.hasOwnProperty.call(c, "_rawProps")).toBe(false);
|
|
24
|
+
expect(Object.prototype.hasOwnProperty.call(c, "_mounted")).toBe(false);
|
|
25
|
+
expect(Object.prototype.hasOwnProperty.call(c, "_anchor")).toBe(false);
|
|
26
|
+
expect(Object.prototype.hasOwnProperty.call(c, "_setProps")).toBe(false);
|
|
23
27
|
});
|
|
24
|
-
it("
|
|
28
|
+
it("mounted starts as false", () => {
|
|
25
29
|
const c = new ConcreteRoot({ name: "" });
|
|
26
|
-
expect(c
|
|
30
|
+
expect(isComponentMounted(c)).toBe(false);
|
|
27
31
|
});
|
|
28
|
-
it("
|
|
32
|
+
it("anchor starts as undefined", () => {
|
|
29
33
|
const c = new ConcreteRoot({ name: "" });
|
|
30
|
-
expect(c
|
|
34
|
+
expect(getComponentAnchor(c)).toBeUndefined();
|
|
31
35
|
});
|
|
32
36
|
it("defaults to empty object when no props given", () => {
|
|
33
37
|
const c = new ConcreteRoot();
|
|
34
|
-
expect(c
|
|
38
|
+
expect(getComponentProps(c)).toEqual({});
|
|
35
39
|
});
|
|
36
40
|
});
|
|
37
41
|
describe("StatefulComponent", () => {
|
|
38
|
-
it("
|
|
42
|
+
it("defaults start as empty object", () => {
|
|
39
43
|
const c = new ConcreteStateful();
|
|
40
|
-
expect(c
|
|
44
|
+
expect(getComponentDefaults(c)).toEqual({});
|
|
41
45
|
});
|
|
42
|
-
it("
|
|
46
|
+
it("stateDirty starts as false", () => {
|
|
43
47
|
const c = new ConcreteStateful();
|
|
44
|
-
expect(c
|
|
48
|
+
expect(isStateDirty(c)).toBe(false);
|
|
45
49
|
});
|
|
46
|
-
it("
|
|
50
|
+
it("setComponentProps replaces raw props contents", () => {
|
|
47
51
|
const c = new ConcreteStateful({ x: 1 });
|
|
48
|
-
c
|
|
49
|
-
|
|
50
|
-
expect(
|
|
52
|
+
setComponentProps(c, { y: 2 });
|
|
53
|
+
const props = getComponentProps(c);
|
|
54
|
+
expect(props.x).toBeUndefined();
|
|
55
|
+
expect(props.y).toBe(2);
|
|
56
|
+
});
|
|
57
|
+
it("updates anchor, mounted, defaults, and dirty state through helpers", () => {
|
|
58
|
+
const c = new ConcreteStateful();
|
|
59
|
+
const anchor = {};
|
|
60
|
+
setComponentAnchor(c, anchor);
|
|
61
|
+
setComponentMounted(c, true);
|
|
62
|
+
setComponentDefault(c, "label", "Save");
|
|
63
|
+
setStateDirty(c, true);
|
|
64
|
+
expect(getComponentAnchor(c)).toBe(anchor);
|
|
65
|
+
expect(isComponentMounted(c)).toBe(true);
|
|
66
|
+
expect(getComponentDefaults(c).label).toBe("Save");
|
|
67
|
+
expect(isStateDirty(c)).toBe(true);
|
|
68
|
+
});
|
|
69
|
+
it("reads raw props and defaults through single-value helpers", () => {
|
|
70
|
+
const c = new ConcreteStateful({ label: "From parent" });
|
|
71
|
+
setComponentDefault(c, "label", "Default");
|
|
72
|
+
expect(getComponentRawProp(c, "label")).toBe("From parent");
|
|
73
|
+
expect(getComponentDefault(c, "label")).toBe("Default");
|
|
74
|
+
});
|
|
75
|
+
it("throws when component internals are read from a non-component", () => {
|
|
76
|
+
expect(() => getComponentProps({})).toThrow(TypeError);
|
|
77
|
+
expect(() => getComponentProps({})).toThrow("Expected a PraxisJS component instance.");
|
|
78
|
+
});
|
|
79
|
+
it("ignores dirty-state writes on non-component hosts", () => {
|
|
80
|
+
const host = {};
|
|
81
|
+
expect(() => markStateDirty(host)).not.toThrow();
|
|
82
|
+
expect(() => setStateDirty(host, true)).not.toThrow();
|
|
83
|
+
expect(isStateDirty(host)).toBe(false);
|
|
51
84
|
});
|
|
52
85
|
});
|
|
53
86
|
class ConcreteStateless extends StatelessComponent {
|
|
@@ -56,19 +89,19 @@ class ConcreteStateless extends StatelessComponent {
|
|
|
56
89
|
}
|
|
57
90
|
}
|
|
58
91
|
describe("StatelessComponent", () => {
|
|
59
|
-
it("stores props
|
|
92
|
+
it("stores props in component internals", () => {
|
|
60
93
|
const c = new ConcreteStateless({ name: "Alice" });
|
|
61
|
-
expect(c.
|
|
94
|
+
expect(getComponentProps(c).name).toBe("Alice");
|
|
62
95
|
});
|
|
63
|
-
it("
|
|
96
|
+
it("setComponentProps replaces raw props contents", () => {
|
|
64
97
|
const c = new ConcreteStateless({ name: "Alice" });
|
|
65
|
-
c
|
|
66
|
-
expect(c.
|
|
98
|
+
setComponentProps(c, { name: "Bob" });
|
|
99
|
+
expect(getComponentProps(c).name).toBe("Bob");
|
|
67
100
|
});
|
|
68
|
-
it("
|
|
101
|
+
it("setComponentProps removes old keys", () => {
|
|
69
102
|
const c = new ConcreteStateless({ name: "Alice" });
|
|
70
|
-
c
|
|
71
|
-
expect(c.
|
|
103
|
+
setComponentProps(c, {});
|
|
104
|
+
expect(getComponentProps(c).name).toBeUndefined();
|
|
72
105
|
});
|
|
73
106
|
it("accepts and exposes children via props.children", () => {
|
|
74
107
|
const c = new ConcreteStateless({ name: "x", children: "hello" });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.test.js","sourceRoot":"","sources":["../../src/__tests__/component.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,YAAa,SAAQ,aAA+B;IACxD,MAAM;QACJ,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,MAAM,gBAAiB,SAAQ,iBAAiB;IAC9C,MAAM;QACJ,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"component.test.js","sourceRoot":"","sources":["../../src/__tests__/component.test.ts"],"names":[],"mappings":"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"}
|
package/dist/component/base.d.ts
CHANGED
|
@@ -1,26 +1,7 @@
|
|
|
1
|
+
import { componentPropsType } from "./internals";
|
|
1
2
|
export declare abstract class RootComponent<T extends object = Record<string, never>> {
|
|
2
|
-
|
|
3
|
-
* Props passed by the parent — filled by the renderer when instantiating/updating.
|
|
4
|
-
* @internal
|
|
5
|
-
*/
|
|
6
|
-
readonly _rawProps: T;
|
|
7
|
-
/**
|
|
8
|
-
* Becomes `true` after `onMount` fires.
|
|
9
|
-
* @internal
|
|
10
|
-
*/
|
|
11
|
-
_mounted: boolean;
|
|
12
|
-
/**
|
|
13
|
-
* End comment anchor set by the runtime; used by decorators to locate the parent element.
|
|
14
|
-
* @internal
|
|
15
|
-
*/
|
|
16
|
-
_anchor?: Comment;
|
|
3
|
+
readonly [componentPropsType]: T;
|
|
17
4
|
constructor(props?: T);
|
|
18
|
-
/**
|
|
19
|
-
* Replaces the current props with a new set; called by the renderer on every parent re-render.
|
|
20
|
-
* @internal
|
|
21
|
-
*/
|
|
22
|
-
_setProps(props: Record<string, unknown>): void;
|
|
23
|
-
get props(): T;
|
|
24
5
|
onBeforeMount?(): void;
|
|
25
6
|
onMount?(): void;
|
|
26
7
|
onUnmount?(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/component/base.ts"],"names":[],"mappings":"AAAA,8BAAsB,aAAa,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IAC1E
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/component/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA0B,MAAM,aAAa,CAAC;AAEzE,8BAAsB,aAAa,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IAC1E,SAAiB,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;gBAE7B,KAAK,GAAE,CAAW;IAI9B,aAAa,CAAC,IAAI,IAAI;IACtB,OAAO,CAAC,IAAI,IAAI;IAChB,SAAS,CAAC,IAAI,IAAI;IAElB,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI;IAE/D,QAAQ,CAAC,MAAM,IAAI,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI;CACxC"}
|
package/dist/component/base.js
CHANGED
|
@@ -1,29 +1,7 @@
|
|
|
1
|
+
import { initComponentInternals } from "./internals";
|
|
1
2
|
export class RootComponent {
|
|
2
3
|
constructor(props = {}) {
|
|
3
|
-
|
|
4
|
-
* Props passed by the parent — filled by the renderer when instantiating/updating.
|
|
5
|
-
* @internal
|
|
6
|
-
*/
|
|
7
|
-
this._rawProps = {};
|
|
8
|
-
/**
|
|
9
|
-
* Becomes `true` after `onMount` fires.
|
|
10
|
-
* @internal
|
|
11
|
-
*/
|
|
12
|
-
this._mounted = false;
|
|
13
|
-
Object.assign(this._rawProps, props);
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Replaces the current props with a new set; called by the renderer on every parent re-render.
|
|
17
|
-
* @internal
|
|
18
|
-
*/
|
|
19
|
-
_setProps(props) {
|
|
20
|
-
Object.keys(this._rawProps).forEach((k) => {
|
|
21
|
-
Reflect.deleteProperty(this._rawProps, k);
|
|
22
|
-
});
|
|
23
|
-
Object.assign(this._rawProps, props);
|
|
24
|
-
}
|
|
25
|
-
get props() {
|
|
26
|
-
return this._rawProps;
|
|
4
|
+
initComponentInternals(this, props);
|
|
27
5
|
}
|
|
28
6
|
}
|
|
29
7
|
//# sourceMappingURL=base.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/component/base.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/component/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAEzE,MAAM,OAAgB,aAAa;IAGjC,YAAY,QAAW,EAAO;QAC5B,sBAAsB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;CASF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const componentPropsType: unique symbol;
|
|
2
|
+
export declare function initComponentInternals(instance: object, props: object): void;
|
|
3
|
+
export declare function getComponentProps(instance: object): object;
|
|
4
|
+
export declare function setComponentProps(instance: object, props: Record<string, unknown>): void;
|
|
5
|
+
export declare function getComponentRawProp(instance: object, name: string): unknown;
|
|
6
|
+
export declare function getComponentDefault(instance: object, name: string): unknown;
|
|
7
|
+
export declare function setComponentDefault(instance: object, name: string, value: unknown): void;
|
|
8
|
+
export declare function getComponentDefaults(instance: object): Record<string, unknown>;
|
|
9
|
+
export declare function getComponentAnchor(instance: object): Comment | undefined;
|
|
10
|
+
export declare function setComponentAnchor(instance: object, anchor: Comment | undefined): void;
|
|
11
|
+
export declare function isComponentMounted(instance: object): boolean;
|
|
12
|
+
export declare function setComponentMounted(instance: object, mounted: boolean): void;
|
|
13
|
+
export declare function markStateDirty(instance: object): void;
|
|
14
|
+
export declare function isStateDirty(instance: object): boolean;
|
|
15
|
+
export declare function setStateDirty(instance: object, stateDirty: boolean): void;
|
|
16
|
+
//# sourceMappingURL=internals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internals.d.ts","sourceRoot":"","sources":["../../src/component/internals.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,EAAE,OAAO,MAA4C,CAAC;AAoBrF,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,IAAI,CAON;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,IAAI,CAMN;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAET;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAET;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,GACb,IAAI,CAEN;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,GACf,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAExE;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,GAAG,SAAS,GAC1B,IAAI,CAEN;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,GACf,IAAI,CAEN;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAKrD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAItD;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,OAAO,GAClB,IAAI,CAKN"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export const componentPropsType = Symbol("praxis.componentPropsType");
|
|
2
|
+
const componentInternals = new WeakMap();
|
|
3
|
+
function getInternals(instance) {
|
|
4
|
+
const internals = componentInternals.get(instance);
|
|
5
|
+
if (!internals) {
|
|
6
|
+
throw new TypeError("Expected a PraxisJS component instance.");
|
|
7
|
+
}
|
|
8
|
+
return internals;
|
|
9
|
+
}
|
|
10
|
+
export function initComponentInternals(instance, props) {
|
|
11
|
+
componentInternals.set(instance, {
|
|
12
|
+
rawProps: { ...props },
|
|
13
|
+
mounted: false,
|
|
14
|
+
defaults: {},
|
|
15
|
+
stateDirty: false,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
export function getComponentProps(instance) {
|
|
19
|
+
return getInternals(instance).rawProps;
|
|
20
|
+
}
|
|
21
|
+
export function setComponentProps(instance, props) {
|
|
22
|
+
const rawProps = getInternals(instance).rawProps;
|
|
23
|
+
Object.keys(rawProps).forEach((key) => {
|
|
24
|
+
Reflect.deleteProperty(rawProps, key);
|
|
25
|
+
});
|
|
26
|
+
Object.assign(rawProps, props);
|
|
27
|
+
}
|
|
28
|
+
export function getComponentRawProp(instance, name) {
|
|
29
|
+
return getInternals(instance).rawProps[name];
|
|
30
|
+
}
|
|
31
|
+
export function getComponentDefault(instance, name) {
|
|
32
|
+
return getInternals(instance).defaults[name];
|
|
33
|
+
}
|
|
34
|
+
export function setComponentDefault(instance, name, value) {
|
|
35
|
+
getInternals(instance).defaults[name] = value;
|
|
36
|
+
}
|
|
37
|
+
export function getComponentDefaults(instance) {
|
|
38
|
+
return getInternals(instance).defaults;
|
|
39
|
+
}
|
|
40
|
+
export function getComponentAnchor(instance) {
|
|
41
|
+
return getInternals(instance).anchor;
|
|
42
|
+
}
|
|
43
|
+
export function setComponentAnchor(instance, anchor) {
|
|
44
|
+
getInternals(instance).anchor = anchor;
|
|
45
|
+
}
|
|
46
|
+
export function isComponentMounted(instance) {
|
|
47
|
+
return getInternals(instance).mounted;
|
|
48
|
+
}
|
|
49
|
+
export function setComponentMounted(instance, mounted) {
|
|
50
|
+
getInternals(instance).mounted = mounted;
|
|
51
|
+
}
|
|
52
|
+
export function markStateDirty(instance) {
|
|
53
|
+
const internals = componentInternals.get(instance);
|
|
54
|
+
if (internals) {
|
|
55
|
+
internals.stateDirty = true;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export function isStateDirty(instance) {
|
|
59
|
+
const internals = componentInternals.get(instance);
|
|
60
|
+
if (internals)
|
|
61
|
+
return internals.stateDirty;
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
export function setStateDirty(instance, stateDirty) {
|
|
65
|
+
const internals = componentInternals.get(instance);
|
|
66
|
+
if (internals) {
|
|
67
|
+
internals.stateDirty = stateDirty;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=internals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internals.js","sourceRoot":"","sources":["../../src/component/internals.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,4 @@
|
|
|
1
1
|
import { RootComponent } from "./base";
|
|
2
2
|
export declare abstract class StatefulComponent extends RootComponent<Record<string, unknown>> {
|
|
3
|
-
/**
|
|
4
|
-
* Default field values declared in the class, used to reset props on update.
|
|
5
|
-
* @internal
|
|
6
|
-
*/
|
|
7
|
-
readonly _defaults: Record<string, unknown>;
|
|
8
|
-
/**
|
|
9
|
-
* Set to `true` by `@State` on any write; cleared by the renderer after each re-render.
|
|
10
|
-
* @internal
|
|
11
|
-
*/
|
|
12
|
-
_stateDirty: boolean;
|
|
13
3
|
}
|
|
14
4
|
//# sourceMappingURL=stateful.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stateful.d.ts","sourceRoot":"","sources":["../../src/component/stateful.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEvC,8BAAsB,iBAAkB,SAAQ,aAAa,CAC3D,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CACxB;
|
|
1
|
+
{"version":3,"file":"stateful.d.ts","sourceRoot":"","sources":["../../src/component/stateful.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEvC,8BAAsB,iBAAkB,SAAQ,aAAa,CAC3D,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CACxB;CAAG"}
|
|
@@ -1,17 +1,4 @@
|
|
|
1
1
|
import { RootComponent } from "./base";
|
|
2
2
|
export class StatefulComponent extends RootComponent {
|
|
3
|
-
constructor() {
|
|
4
|
-
super(...arguments);
|
|
5
|
-
/**
|
|
6
|
-
* Default field values declared in the class, used to reset props on update.
|
|
7
|
-
* @internal
|
|
8
|
-
*/
|
|
9
|
-
this._defaults = {};
|
|
10
|
-
/**
|
|
11
|
-
* Set to `true` by `@State` on any write; cleared by the renderer after each re-render.
|
|
12
|
-
* @internal
|
|
13
|
-
*/
|
|
14
|
-
this._stateDirty = false;
|
|
15
|
-
}
|
|
16
3
|
}
|
|
17
4
|
//# sourceMappingURL=stateful.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stateful.js","sourceRoot":"","sources":["../../src/component/stateful.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEvC,MAAM,OAAgB,iBAAkB,SAAQ,aAE/C;
|
|
1
|
+
{"version":3,"file":"stateful.js","sourceRoot":"","sources":["../../src/component/stateful.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEvC,MAAM,OAAgB,iBAAkB,SAAQ,aAE/C;CAAG"}
|
|
@@ -4,6 +4,8 @@ type StatelessComponentType<T> = T & {
|
|
|
4
4
|
children?: Children;
|
|
5
5
|
};
|
|
6
6
|
export declare abstract class StatelessComponent<T extends object = Record<never, never>> extends RootComponent<StatelessComponentType<T>> {
|
|
7
|
+
/** Public props API for presentational components. */
|
|
8
|
+
get props(): StatelessComponentType<T>;
|
|
7
9
|
}
|
|
8
10
|
export {};
|
|
9
11
|
//# sourceMappingURL=stateless.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stateless.d.ts","sourceRoot":"","sources":["../../src/component/stateless.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"stateless.d.ts","sourceRoot":"","sources":["../../src/component/stateless.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAGvC,KAAK,sBAAsB,CAAC,CAAC,IAAI,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,QAAQ,CAAA;CAAE,CAAC;AAE7D,8BAAsB,kBAAkB,CACtC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CACvC,SAAQ,aAAa,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAChD,sDAAsD;IACtD,IAAI,KAAK,IAAI,sBAAsB,CAAC,CAAC,CAAC,CAErC;CACF"}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { RootComponent } from "./base";
|
|
2
|
+
import { getComponentProps } from "./internals";
|
|
2
3
|
export class StatelessComponent extends RootComponent {
|
|
4
|
+
/** Public props API for presentational components. */
|
|
5
|
+
get props() {
|
|
6
|
+
return getComponentProps(this);
|
|
7
|
+
}
|
|
3
8
|
}
|
|
4
9
|
//# sourceMappingURL=stateless.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stateless.js","sourceRoot":"","sources":["../../src/component/stateless.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"stateless.js","sourceRoot":"","sources":["../../src/component/stateless.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIhD,MAAM,OAAgB,kBAEpB,SAAQ,aAAwC;IAChD,sDAAsD;IACtD,IAAI,KAAK;QACP,OAAO,iBAAiB,CAAC,IAAI,CAA8B,CAAC;IAC9D,CAAC;CACF"}
|
package/dist/internal.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { debounced, until, when, history, type HistoryElement, } from "./reactive";
|
|
2
2
|
export { signal, persistedSignal, syncedSignal, peek, computed, writableComputed, batch, effect, untrack, type PersistedSignalOptions, type SyncedSignal, } from "./signal";
|
|
3
3
|
export { RootComponent } from "./component";
|
|
4
|
+
export { componentPropsType, getComponentAnchor, getComponentDefault, getComponentDefaults, getComponentProps, getComponentRawProp, isComponentMounted, isStateDirty, markStateDirty, setComponentAnchor, setComponentDefault, setComponentMounted, setComponentProps, setStateDirty, } from "./component/internals";
|
|
4
5
|
export { resource, createResource, type ResourceStatus, type Resource, type ResourceOptions, } from "./async/resource";
|
|
5
6
|
export { invalidateResource, _clearCache } from "./async/resource-cache";
|
|
6
7
|
//# sourceMappingURL=internal.d.ts.map
|
package/dist/internal.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,KAAK,EACL,IAAI,EACJ,OAAO,EACP,KAAK,cAAc,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,MAAM,EACN,eAAe,EACf,YAAY,EACZ,IAAI,EACJ,QAAQ,EACR,gBAAgB,EAChB,KAAK,EACL,MAAM,EACN,OAAO,EACP,KAAK,sBAAsB,EAC3B,KAAK,YAAY,GAClB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACL,QAAQ,EACR,cAAc,EACd,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,eAAe,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,KAAK,EACL,IAAI,EACJ,OAAO,EACP,KAAK,cAAc,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,MAAM,EACN,eAAe,EACf,YAAY,EACZ,IAAI,EACJ,QAAQ,EACR,gBAAgB,EAChB,KAAK,EACL,MAAM,EACN,OAAO,EACP,KAAK,sBAAsB,EAC3B,KAAK,YAAY,GAClB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,QAAQ,EACR,cAAc,EACd,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,eAAe,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC"}
|
package/dist/internal.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { debounced, until, when, history, } from "./reactive";
|
|
2
2
|
export { signal, persistedSignal, syncedSignal, peek, computed, writableComputed, batch, effect, untrack, } from "./signal";
|
|
3
3
|
export { RootComponent } from "./component";
|
|
4
|
+
export { componentPropsType, getComponentAnchor, getComponentDefault, getComponentDefaults, getComponentProps, getComponentRawProp, isComponentMounted, isStateDirty, markStateDirty, setComponentAnchor, setComponentDefault, setComponentMounted, setComponentProps, setStateDirty, } from "./component/internals";
|
|
4
5
|
export { resource, createResource, } from "./async/resource";
|
|
5
6
|
export { invalidateResource, _clearCache } from "./async/resource-cache";
|
|
6
7
|
//# sourceMappingURL=internal.js.map
|
package/dist/internal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,KAAK,EACL,IAAI,EACJ,OAAO,GAER,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,MAAM,EACN,eAAe,EACf,YAAY,EACZ,IAAI,EACJ,QAAQ,EACR,gBAAgB,EAChB,KAAK,EACL,MAAM,EACN,OAAO,GAGR,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACL,QAAQ,EACR,cAAc,GAIf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,KAAK,EACL,IAAI,EACJ,OAAO,GAER,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,MAAM,EACN,eAAe,EACf,YAAY,EACZ,IAAI,EACJ,QAAQ,EACR,gBAAgB,EAChB,KAAK,EACL,MAAM,EACN,OAAO,GAGR,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,QAAQ,EACR,cAAc,GAIf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisjs/core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"typescript": "^5.9.3"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@praxisjs/shared": "0.3.
|
|
21
|
+
"@praxisjs/shared": "0.3.1"
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
24
|
"build": "tsc",
|
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
2
|
|
|
3
3
|
import { RootComponent } from "../component/base";
|
|
4
|
+
import {
|
|
5
|
+
getComponentAnchor,
|
|
6
|
+
getComponentDefault,
|
|
7
|
+
getComponentDefaults,
|
|
8
|
+
getComponentProps,
|
|
9
|
+
getComponentRawProp,
|
|
10
|
+
isComponentMounted,
|
|
11
|
+
isStateDirty,
|
|
12
|
+
markStateDirty,
|
|
13
|
+
setComponentAnchor,
|
|
14
|
+
setComponentDefault,
|
|
15
|
+
setComponentMounted,
|
|
16
|
+
setComponentProps,
|
|
17
|
+
setStateDirty,
|
|
18
|
+
} from "../component/internals";
|
|
4
19
|
import { StatefulComponent } from "../component/stateful";
|
|
5
20
|
import { StatelessComponent } from "../component/stateless";
|
|
6
21
|
|
|
@@ -17,48 +32,90 @@ class ConcreteStateful extends StatefulComponent {
|
|
|
17
32
|
}
|
|
18
33
|
|
|
19
34
|
describe("RootComponent", () => {
|
|
20
|
-
it("stores props
|
|
35
|
+
it("stores props in component internals", () => {
|
|
21
36
|
const c = new ConcreteRoot({ name: "Alice" });
|
|
22
|
-
expect(c.
|
|
37
|
+
expect((getComponentProps(c) as { name: string }).name).toBe("Alice");
|
|
23
38
|
});
|
|
24
39
|
|
|
25
|
-
it("
|
|
26
|
-
const c = new ConcreteRoot({ name: "
|
|
27
|
-
expect(
|
|
40
|
+
it("does not expose old underscore internals as own properties", () => {
|
|
41
|
+
const c = new ConcreteRoot({ name: "Alice" });
|
|
42
|
+
expect(Object.prototype.hasOwnProperty.call(c, "_rawProps")).toBe(false);
|
|
43
|
+
expect(Object.prototype.hasOwnProperty.call(c, "_mounted")).toBe(false);
|
|
44
|
+
expect(Object.prototype.hasOwnProperty.call(c, "_anchor")).toBe(false);
|
|
45
|
+
expect(Object.prototype.hasOwnProperty.call(c, "_setProps")).toBe(false);
|
|
28
46
|
});
|
|
29
47
|
|
|
30
|
-
it("
|
|
48
|
+
it("mounted starts as false", () => {
|
|
31
49
|
const c = new ConcreteRoot({ name: "" });
|
|
32
|
-
expect(c
|
|
50
|
+
expect(isComponentMounted(c)).toBe(false);
|
|
33
51
|
});
|
|
34
52
|
|
|
35
|
-
it("
|
|
53
|
+
it("anchor starts as undefined", () => {
|
|
36
54
|
const c = new ConcreteRoot({ name: "" });
|
|
37
|
-
expect(c
|
|
55
|
+
expect(getComponentAnchor(c)).toBeUndefined();
|
|
38
56
|
});
|
|
39
57
|
|
|
40
58
|
it("defaults to empty object when no props given", () => {
|
|
41
59
|
const c = new ConcreteRoot();
|
|
42
|
-
expect(c
|
|
60
|
+
expect(getComponentProps(c)).toEqual({});
|
|
43
61
|
});
|
|
44
62
|
});
|
|
45
63
|
|
|
46
64
|
describe("StatefulComponent", () => {
|
|
47
|
-
it("
|
|
65
|
+
it("defaults start as empty object", () => {
|
|
48
66
|
const c = new ConcreteStateful();
|
|
49
|
-
expect(c
|
|
67
|
+
expect(getComponentDefaults(c)).toEqual({});
|
|
50
68
|
});
|
|
51
69
|
|
|
52
|
-
it("
|
|
70
|
+
it("stateDirty starts as false", () => {
|
|
53
71
|
const c = new ConcreteStateful();
|
|
54
|
-
expect(c
|
|
72
|
+
expect(isStateDirty(c)).toBe(false);
|
|
55
73
|
});
|
|
56
74
|
|
|
57
|
-
it("
|
|
75
|
+
it("setComponentProps replaces raw props contents", () => {
|
|
58
76
|
const c = new ConcreteStateful({ x: 1 });
|
|
59
|
-
c
|
|
60
|
-
|
|
61
|
-
expect(
|
|
77
|
+
setComponentProps(c, { y: 2 });
|
|
78
|
+
const props = getComponentProps(c) as Record<string, unknown>;
|
|
79
|
+
expect(props.x).toBeUndefined();
|
|
80
|
+
expect(props.y).toBe(2);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("updates anchor, mounted, defaults, and dirty state through helpers", () => {
|
|
84
|
+
const c = new ConcreteStateful();
|
|
85
|
+
const anchor = {} as Comment;
|
|
86
|
+
|
|
87
|
+
setComponentAnchor(c, anchor);
|
|
88
|
+
setComponentMounted(c, true);
|
|
89
|
+
setComponentDefault(c, "label", "Save");
|
|
90
|
+
setStateDirty(c, true);
|
|
91
|
+
|
|
92
|
+
expect(getComponentAnchor(c)).toBe(anchor);
|
|
93
|
+
expect(isComponentMounted(c)).toBe(true);
|
|
94
|
+
expect(getComponentDefaults(c).label).toBe("Save");
|
|
95
|
+
expect(isStateDirty(c)).toBe(true);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("reads raw props and defaults through single-value helpers", () => {
|
|
99
|
+
const c = new ConcreteStateful({ label: "From parent" });
|
|
100
|
+
setComponentDefault(c, "label", "Default");
|
|
101
|
+
|
|
102
|
+
expect(getComponentRawProp(c, "label")).toBe("From parent");
|
|
103
|
+
expect(getComponentDefault(c, "label")).toBe("Default");
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("throws when component internals are read from a non-component", () => {
|
|
107
|
+
expect(() => getComponentProps({})).toThrow(TypeError);
|
|
108
|
+
expect(() => getComponentProps({})).toThrow(
|
|
109
|
+
"Expected a PraxisJS component instance.",
|
|
110
|
+
);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("ignores dirty-state writes on non-component hosts", () => {
|
|
114
|
+
const host = {};
|
|
115
|
+
|
|
116
|
+
expect(() => markStateDirty(host)).not.toThrow();
|
|
117
|
+
expect(() => setStateDirty(host, true)).not.toThrow();
|
|
118
|
+
expect(isStateDirty(host)).toBe(false);
|
|
62
119
|
});
|
|
63
120
|
});
|
|
64
121
|
|
|
@@ -69,21 +126,21 @@ class ConcreteStateless extends StatelessComponent<{ name: string }> {
|
|
|
69
126
|
}
|
|
70
127
|
|
|
71
128
|
describe("StatelessComponent", () => {
|
|
72
|
-
it("stores props
|
|
129
|
+
it("stores props in component internals", () => {
|
|
73
130
|
const c = new ConcreteStateless({ name: "Alice" });
|
|
74
|
-
expect(c.
|
|
131
|
+
expect((getComponentProps(c) as { name: string }).name).toBe("Alice");
|
|
75
132
|
});
|
|
76
133
|
|
|
77
|
-
it("
|
|
134
|
+
it("setComponentProps replaces raw props contents", () => {
|
|
78
135
|
const c = new ConcreteStateless({ name: "Alice" });
|
|
79
|
-
c
|
|
80
|
-
expect(c.
|
|
136
|
+
setComponentProps(c, { name: "Bob" });
|
|
137
|
+
expect((getComponentProps(c) as { name: string }).name).toBe("Bob");
|
|
81
138
|
});
|
|
82
139
|
|
|
83
|
-
it("
|
|
140
|
+
it("setComponentProps removes old keys", () => {
|
|
84
141
|
const c = new ConcreteStateless({ name: "Alice" });
|
|
85
|
-
c
|
|
86
|
-
expect((c
|
|
142
|
+
setComponentProps(c, {});
|
|
143
|
+
expect((getComponentProps(c) as Record<string, unknown>).name).toBeUndefined();
|
|
87
144
|
});
|
|
88
145
|
|
|
89
146
|
it("accepts and exposes children via props.children", () => {
|
package/src/component/base.ts
CHANGED
|
@@ -1,39 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* Props passed by the parent — filled by the renderer when instantiating/updating.
|
|
4
|
-
* @internal
|
|
5
|
-
*/
|
|
6
|
-
readonly _rawProps: T = {} as T;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Becomes `true` after `onMount` fires.
|
|
10
|
-
* @internal
|
|
11
|
-
*/
|
|
12
|
-
_mounted = false;
|
|
1
|
+
import { componentPropsType, initComponentInternals } from "./internals";
|
|
13
2
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
* @internal
|
|
17
|
-
*/
|
|
18
|
-
_anchor?: Comment;
|
|
3
|
+
export abstract class RootComponent<T extends object = Record<string, never>> {
|
|
4
|
+
declare readonly [componentPropsType]: T;
|
|
19
5
|
|
|
20
6
|
constructor(props: T = {} as T) {
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Replaces the current props with a new set; called by the renderer on every parent re-render.
|
|
26
|
-
* @internal
|
|
27
|
-
*/
|
|
28
|
-
_setProps(props: Record<string, unknown>) {
|
|
29
|
-
Object.keys(this._rawProps).forEach((k) => {
|
|
30
|
-
Reflect.deleteProperty(this._rawProps, k);
|
|
31
|
-
});
|
|
32
|
-
Object.assign(this._rawProps, props);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
get props(): T {
|
|
36
|
-
return this._rawProps;
|
|
7
|
+
initComponentInternals(this, props);
|
|
37
8
|
}
|
|
38
9
|
|
|
39
10
|
onBeforeMount?(): void;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
export const componentPropsType: unique symbol = Symbol("praxis.componentPropsType");
|
|
2
|
+
|
|
3
|
+
interface ComponentInternals<T extends object> {
|
|
4
|
+
rawProps: T;
|
|
5
|
+
mounted: boolean;
|
|
6
|
+
anchor?: Comment;
|
|
7
|
+
defaults: Record<string, unknown>;
|
|
8
|
+
stateDirty: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const componentInternals = new WeakMap<object, ComponentInternals<object>>();
|
|
12
|
+
|
|
13
|
+
function getInternals(instance: object): ComponentInternals<object> {
|
|
14
|
+
const internals = componentInternals.get(instance);
|
|
15
|
+
if (!internals) {
|
|
16
|
+
throw new TypeError("Expected a PraxisJS component instance.");
|
|
17
|
+
}
|
|
18
|
+
return internals;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function initComponentInternals(
|
|
22
|
+
instance: object,
|
|
23
|
+
props: object,
|
|
24
|
+
): void {
|
|
25
|
+
componentInternals.set(instance, {
|
|
26
|
+
rawProps: { ...props },
|
|
27
|
+
mounted: false,
|
|
28
|
+
defaults: {},
|
|
29
|
+
stateDirty: false,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function getComponentProps(instance: object): object {
|
|
34
|
+
return getInternals(instance).rawProps;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function setComponentProps(
|
|
38
|
+
instance: object,
|
|
39
|
+
props: Record<string, unknown>,
|
|
40
|
+
): void {
|
|
41
|
+
const rawProps = getInternals(instance).rawProps as Record<string, unknown>;
|
|
42
|
+
Object.keys(rawProps).forEach((key) => {
|
|
43
|
+
Reflect.deleteProperty(rawProps, key);
|
|
44
|
+
});
|
|
45
|
+
Object.assign(rawProps, props);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function getComponentRawProp(
|
|
49
|
+
instance: object,
|
|
50
|
+
name: string,
|
|
51
|
+
): unknown {
|
|
52
|
+
return (getInternals(instance).rawProps as Record<string, unknown>)[name];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function getComponentDefault(
|
|
56
|
+
instance: object,
|
|
57
|
+
name: string,
|
|
58
|
+
): unknown {
|
|
59
|
+
return getInternals(instance).defaults[name];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function setComponentDefault(
|
|
63
|
+
instance: object,
|
|
64
|
+
name: string,
|
|
65
|
+
value: unknown,
|
|
66
|
+
): void {
|
|
67
|
+
getInternals(instance).defaults[name] = value;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function getComponentDefaults(
|
|
71
|
+
instance: object,
|
|
72
|
+
): Record<string, unknown> {
|
|
73
|
+
return getInternals(instance).defaults;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function getComponentAnchor(instance: object): Comment | undefined {
|
|
77
|
+
return getInternals(instance).anchor;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function setComponentAnchor(
|
|
81
|
+
instance: object,
|
|
82
|
+
anchor: Comment | undefined,
|
|
83
|
+
): void {
|
|
84
|
+
getInternals(instance).anchor = anchor;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function isComponentMounted(instance: object): boolean {
|
|
88
|
+
return getInternals(instance).mounted;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function setComponentMounted(
|
|
92
|
+
instance: object,
|
|
93
|
+
mounted: boolean,
|
|
94
|
+
): void {
|
|
95
|
+
getInternals(instance).mounted = mounted;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function markStateDirty(instance: object): void {
|
|
99
|
+
const internals = componentInternals.get(instance);
|
|
100
|
+
if (internals) {
|
|
101
|
+
internals.stateDirty = true;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function isStateDirty(instance: object): boolean {
|
|
106
|
+
const internals = componentInternals.get(instance);
|
|
107
|
+
if (internals) return internals.stateDirty;
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function setStateDirty(
|
|
112
|
+
instance: object,
|
|
113
|
+
stateDirty: boolean,
|
|
114
|
+
): void {
|
|
115
|
+
const internals = componentInternals.get(instance);
|
|
116
|
+
if (internals) {
|
|
117
|
+
internals.stateDirty = stateDirty;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -2,17 +2,4 @@ import { RootComponent } from "./base";
|
|
|
2
2
|
|
|
3
3
|
export abstract class StatefulComponent extends RootComponent<
|
|
4
4
|
Record<string, unknown>
|
|
5
|
-
> {
|
|
6
|
-
/**
|
|
7
|
-
* Default field values declared in the class, used to reset props on update.
|
|
8
|
-
* @internal
|
|
9
|
-
*/
|
|
10
|
-
readonly _defaults: Record<string, unknown> = {};
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Set to `true` by `@State` on any write; cleared by the renderer after each re-render.
|
|
14
|
-
* @internal
|
|
15
|
-
*/
|
|
16
|
-
_stateDirty = false;
|
|
17
|
-
|
|
18
|
-
}
|
|
5
|
+
> {}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import type { Children } from "@praxisjs/shared";
|
|
2
2
|
|
|
3
3
|
import { RootComponent } from "./base";
|
|
4
|
+
import { getComponentProps } from "./internals";
|
|
4
5
|
|
|
5
6
|
type StatelessComponentType<T> = T & { children?: Children };
|
|
6
7
|
|
|
7
8
|
export abstract class StatelessComponent<
|
|
8
9
|
T extends object = Record<never, never>,
|
|
9
10
|
> extends RootComponent<StatelessComponentType<T>> {
|
|
11
|
+
/** Public props API for presentational components. */
|
|
12
|
+
get props(): StatelessComponentType<T> {
|
|
13
|
+
return getComponentProps(this) as StatelessComponentType<T>;
|
|
14
|
+
}
|
|
10
15
|
}
|
package/src/internal.ts
CHANGED
|
@@ -19,6 +19,22 @@ export {
|
|
|
19
19
|
type SyncedSignal,
|
|
20
20
|
} from "./signal";
|
|
21
21
|
export { RootComponent } from "./component";
|
|
22
|
+
export {
|
|
23
|
+
componentPropsType,
|
|
24
|
+
getComponentAnchor,
|
|
25
|
+
getComponentDefault,
|
|
26
|
+
getComponentDefaults,
|
|
27
|
+
getComponentProps,
|
|
28
|
+
getComponentRawProp,
|
|
29
|
+
isComponentMounted,
|
|
30
|
+
isStateDirty,
|
|
31
|
+
markStateDirty,
|
|
32
|
+
setComponentAnchor,
|
|
33
|
+
setComponentDefault,
|
|
34
|
+
setComponentMounted,
|
|
35
|
+
setComponentProps,
|
|
36
|
+
setStateDirty,
|
|
37
|
+
} from "./component/internals";
|
|
22
38
|
export {
|
|
23
39
|
resource,
|
|
24
40
|
createResource,
|