effectable 1.2.0-canary.10 → 1.2.0-canary.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.
|
@@ -5,6 +5,12 @@
|
|
|
5
5
|
* Holds `state`, updates it via {@link Component.setState}, and after each update calls
|
|
6
6
|
* {@link Component.onUpdate}.
|
|
7
7
|
*
|
|
8
|
+
* **Single writer:** only {@link Component.setState} may change state after construction
|
|
9
|
+
* (triggers `onUpdate` and reconcile schedule). Direct `this.state = …` after init emits
|
|
10
|
+
* `console.warn` and does **not** change `#state`. Constructor init (`super(props, initial)`
|
|
11
|
+
* or `this.state = …` in the constructor body) is allowed without warning. If reconciliation
|
|
12
|
+
* is not needed, use a ref.
|
|
13
|
+
*
|
|
8
14
|
* **Modes:**
|
|
9
15
|
* - **Standalone** — `Component` as a lightweight stateful object without GraphRuntime: `setState`
|
|
10
16
|
* immediately leads to `onUpdate`, with no “only after mount” restriction.
|
|
@@ -50,6 +56,7 @@ export type SetStateUpdate<S, P = unknown> = Partial<S> | ((prevState: S, props:
|
|
|
50
56
|
* ```
|
|
51
57
|
*/
|
|
52
58
|
export declare abstract class Component<S = unknown, P = unknown> implements Lifecycle {
|
|
59
|
+
#private;
|
|
53
60
|
/**
|
|
54
61
|
* Opt-in flag for HFT components: if `true`, {@link Component.setState} applies
|
|
55
62
|
* updates **in-place** on the current `this.state` instead of creating a new object via spread.
|
|
@@ -66,10 +73,19 @@ export declare abstract class Component<S = unknown, P = unknown> implements Lif
|
|
|
66
73
|
* ```
|
|
67
74
|
*/
|
|
68
75
|
static readonly mutableState: boolean;
|
|
69
|
-
/** Current instance state after the last assignment in {@link Component.setState}. */
|
|
70
|
-
state: S;
|
|
71
76
|
/** Instance inputs: filled by GraphRuntime, connect-HOC, or calling code. */
|
|
72
77
|
props: P;
|
|
78
|
+
/**
|
|
79
|
+
* Current instance state after the last commit in {@link Component.setState}
|
|
80
|
+
* (or constructor init). Read freely; do not assign after construction — use `setState`.
|
|
81
|
+
*/
|
|
82
|
+
get state(): S;
|
|
83
|
+
/**
|
|
84
|
+
* Direct assignment after construction is forbidden: emits {@link console.warn} and leaves
|
|
85
|
+
* `#state` unchanged (no write, no `onUpdate`, no reconcile). Prefer {@link Component.setState}.
|
|
86
|
+
* Allowed without warning during construction (`super(props, initial)` or subclass ctor body).
|
|
87
|
+
*/
|
|
88
|
+
set state(value: S);
|
|
73
89
|
/**
|
|
74
90
|
* @param {P} props Props available in the {@link Component.setState} callback and in the subclass.
|
|
75
91
|
* @param {S} [initialState] Initial state; if omitted, an empty object is used as `S`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Component.d.ts","sourceRoot":"","sources":["../../src/component/Component.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"Component.d.ts","sourceRoot":"","sources":["../../src/component/Component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAGlD;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,IACrC,OAAO,CAAC,CAAC,CAAC,GACV,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAQ7C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,8BAAsB,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,CACxD,YAAW,SAAS;;IAClB;;;;;;;;;;;;;;OAcG;IACH,gBAAuB,YAAY,EAAE,OAAO,CAAS;IAWrD,6EAA6E;IACtE,KAAK,EAAE,CAAC,CAAC;IAEhB;;;OAGG;IACH,IAAW,KAAK,IAAK,CAAC,CAErB;IAED;;;;OAIG;IACH,IAAW,KAAK,CAAE,KAAK,EAAE,CAAC,EAMzB;IAED;;;OAGG;gBACU,KAAK,EAAE,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC;IAWvC;;;;;;;;;OASG;IACI,QAAQ,CAAE,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI;IAoCpD;;;;;;;;;OASG;IACI,QAAQ,CAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAI1C;;;;;;OAMG;IACH,OAAO,CAAC,IAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAEjC;;;;;OAKG;IACH,SAAS,CAAC,IAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAEnC;;;;;;;;OAQG;IACH,OAAO,CAAC,IAAK,kBAAkB,GAAG,kBAAkB,EAAE,GAAG,IAAI;CAC9D"}
|
|
@@ -6,6 +6,12 @@
|
|
|
6
6
|
* Holds `state`, updates it via {@link Component.setState}, and after each update calls
|
|
7
7
|
* {@link Component.onUpdate}.
|
|
8
8
|
*
|
|
9
|
+
* **Single writer:** only {@link Component.setState} may change state after construction
|
|
10
|
+
* (triggers `onUpdate` and reconcile schedule). Direct `this.state = …` after init emits
|
|
11
|
+
* `console.warn` and does **not** change `#state`. Constructor init (`super(props, initial)`
|
|
12
|
+
* or `this.state = …` in the constructor body) is allowed without warning. If reconciliation
|
|
13
|
+
* is not needed, use a ref.
|
|
14
|
+
*
|
|
9
15
|
* **Modes:**
|
|
10
16
|
* - **Standalone** — `Component` as a lightweight stateful object without GraphRuntime: `setState`
|
|
11
17
|
* immediately leads to `onUpdate`, with no “only after mount” restriction.
|
|
@@ -21,6 +27,10 @@
|
|
|
21
27
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
28
|
exports.Component = void 0;
|
|
23
29
|
const types_1 = require("./types");
|
|
30
|
+
/** Warn text for forbidden direct `this.state =` after construction. */
|
|
31
|
+
const DIRECT_STATE_ASSIGNMENT_WARN = '[Effectable] Component: direct assignment to `state` is not supported. ' +
|
|
32
|
+
'Use `setState(...)` so `onUpdate` and reconcile run. ' +
|
|
33
|
+
'If you do not need reconciliation, store the value in a ref (`@UseRef`) instead of state.';
|
|
24
34
|
/**
|
|
25
35
|
* Abstract base class with state and lifecycle.
|
|
26
36
|
* Implements the {@link Lifecycle} contract: `onMount` → `onUpdate*` → `onUnmount`.
|
|
@@ -60,17 +70,47 @@ class Component {
|
|
|
60
70
|
* ```
|
|
61
71
|
*/
|
|
62
72
|
static mutableState = false;
|
|
63
|
-
/**
|
|
64
|
-
state;
|
|
73
|
+
/** Backing store for {@link Component.state}. Written only by init, setter, or {@link Component.setState}. */
|
|
74
|
+
#state;
|
|
75
|
+
/**
|
|
76
|
+
* When `true`, direct `this.state =` does not warn (constructor init window).
|
|
77
|
+
* Closed after the full `new` constructor chain finishes (microtask).
|
|
78
|
+
*/
|
|
79
|
+
#allowDirectStateWrite;
|
|
65
80
|
/** Instance inputs: filled by GraphRuntime, connect-HOC, or calling code. */
|
|
66
81
|
props;
|
|
82
|
+
/**
|
|
83
|
+
* Current instance state after the last commit in {@link Component.setState}
|
|
84
|
+
* (or constructor init). Read freely; do not assign after construction — use `setState`.
|
|
85
|
+
*/
|
|
86
|
+
get state() {
|
|
87
|
+
return this.#state;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Direct assignment after construction is forbidden: emits {@link console.warn} and leaves
|
|
91
|
+
* `#state` unchanged (no write, no `onUpdate`, no reconcile). Prefer {@link Component.setState}.
|
|
92
|
+
* Allowed without warning during construction (`super(props, initial)` or subclass ctor body).
|
|
93
|
+
*/
|
|
94
|
+
set state(value) {
|
|
95
|
+
if (!this.#allowDirectStateWrite) {
|
|
96
|
+
console.warn(DIRECT_STATE_ASSIGNMENT_WARN);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
this.#state = value;
|
|
100
|
+
}
|
|
67
101
|
/**
|
|
68
102
|
* @param {P} props Props available in the {@link Component.setState} callback and in the subclass.
|
|
69
103
|
* @param {S} [initialState] Initial state; if omitted, an empty object is used as `S`.
|
|
70
104
|
*/
|
|
71
105
|
constructor(props, initialState) {
|
|
72
106
|
this.props = props;
|
|
73
|
-
this
|
|
107
|
+
this.#allowDirectStateWrite = true;
|
|
108
|
+
this.#state = (initialState ?? {});
|
|
109
|
+
// Subclass constructor bodies run synchronously after `super()` and may assign `this.state`.
|
|
110
|
+
// Close the gate once the full `new` constructor chain has finished.
|
|
111
|
+
queueMicrotask(() => {
|
|
112
|
+
this.#allowDirectStateWrite = false;
|
|
113
|
+
});
|
|
74
114
|
}
|
|
75
115
|
/**
|
|
76
116
|
* Computes the next state as a shallow merge of `prev` with the update object or with the
|
|
@@ -83,7 +123,7 @@ class Component {
|
|
|
83
123
|
* @returns {void}
|
|
84
124
|
*/
|
|
85
125
|
setState(update) {
|
|
86
|
-
const prev = this
|
|
126
|
+
const prev = this.#state;
|
|
87
127
|
const delta = typeof update === 'function'
|
|
88
128
|
? update(prev, this.props)
|
|
89
129
|
: update;
|
|
@@ -107,7 +147,7 @@ class Component {
|
|
|
107
147
|
}
|
|
108
148
|
// Shallow-copy previous state and delta to avoid mutating the original state
|
|
109
149
|
const next = { ...prev, ...delta };
|
|
110
|
-
this
|
|
150
|
+
this.#state = next;
|
|
111
151
|
// State is already committed: always schedule even if onUpdate throws,
|
|
112
152
|
// otherwise mounted compose/children stay stale after a successful write.
|
|
113
153
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Component.js","sourceRoot":"","sources":["../../src/component/Component.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"Component.js","sourceRoot":"","sources":["../../src/component/Component.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;;;AAIH,mCAA+C;AAa/C,wEAAwE;AACxE,MAAM,4BAA4B,GAChC,yEAAyE;IACzE,uDAAuD;IACvD,2FAA2F,CAAC;AAE9F;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAsB,SAAS;IAE7B;;;;;;;;;;;;;;OAcG;IACI,MAAM,CAAU,YAAY,GAAY,KAAK,CAAC;IAErD,8GAA8G;IAC9G,MAAM,CAAI;IAEV;;;OAGG;IACH,sBAAsB,CAAU;IAEhC,6EAA6E;IACtE,KAAK,CAAI;IAEhB;;;OAGG;IACH,IAAW,KAAK;QACd,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;;;OAIG;IACH,IAAW,KAAK,CAAE,KAAQ;QACxB,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE,CAAC;YACjC,OAAO,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;YAC3C,OAAO;QACT,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED;;;OAGG;IACH,YAAa,KAAQ,EAAE,YAAgB;QACrC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;QACnC,IAAI,CAAC,MAAM,GAAG,CAAC,YAAY,IAAI,EAAE,CAAM,CAAC;QACxC,6FAA6F;QAC7F,qEAAqE;QACrE,cAAc,CAAC,GAAG,EAAE;YAClB,IAAI,CAAC,sBAAsB,GAAG,KAAK,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;OASG;IACI,QAAQ,CAAE,MAA4B;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC;QACzB,MAAM,KAAK,GAAG,OAAO,MAAM,KAAK,UAAU;YACxC,CAAC,CAAE,MAA4C,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC;YACjE,CAAC,CAAC,MAAM,CAAC;QAEX,yEAAyE;QACzE,+DAA+D;QAC/D,IAAK,IAAI,CAAC,WAA0C,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;YAC3E,MAAM,MAAM,GAAG,IAA0C,CAAC;YAC1D,MAAM,GAAG,GAAG,KAA2C,CAAC;YACxD,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;gBACpB,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;YACrB,CAAC;YACD,uEAAuE;YACvE,0EAA0E;YAC1E,IAAI,CAAC;gBACH,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC5B,CAAC;oBAAS,CAAC;gBACR,IAA2D,CAAC,4BAAoB,CAAC,EAAE,EAAE,CAAC;YACzF,CAAC;YACD,OAAO;QACT,CAAC;QAED,6EAA6E;QAC7E,MAAM,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC;QACnC,IAAI,CAAC,MAAM,GAAG,IAAS,CAAC;QACxB,uEAAuE;QACvE,0EAA0E;QAC1E,IAAI,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5B,CAAC;gBAAS,CAAC;YACR,IAA2D,CAAC,4BAAoB,CAAC,EAAE,EAAE,CAAC;QACzF,CAAC;IACH,CAAC;IAED;;;;;;;;;OASG;IACI,QAAQ,CAAE,KAAQ,EAAE,KAAQ;QACjC,kDAAkD;IACpD,CAAC;;AA7HH,8BA0JC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "effectable",
|
|
3
|
-
"version": "1.2.0-canary.
|
|
3
|
+
"version": "1.2.0-canary.11",
|
|
4
4
|
"description": "Declarative reactive runtime for Node.js: bootstrap, Redux-style RxJS store, Component lifecycle, class-based connect, and GraphRuntime.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|