nesquick 0.0.26 → 1.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/lib/NesquickComponent.js +5 -5
- package/lib/State.js +69 -17
- package/lib/cli/transformer.js +86 -25
- package/lib/jsx-runtime.js +5 -0
- package/lib/no-transformer/jsx-runtime.js +1 -0
- package/lib/types/State.d.ts +11 -5
- package/lib/types/jsx-runtime.d.ts +4 -1
- package/lib/types/no-transformer/jsx-runtime.d.ts +1 -0
- package/package.json +1 -1
package/lib/NesquickComponent.js
CHANGED
|
@@ -161,7 +161,7 @@ class NesquickComponent {
|
|
|
161
161
|
_renderStyle(element, style) {
|
|
162
162
|
switch (typeof style) {
|
|
163
163
|
case "function": {
|
|
164
|
-
(0, State_1.useRender)(style, (style,
|
|
164
|
+
(0, State_1.useRender)(style, (style, lastReaction) => {
|
|
165
165
|
if (this._styleSubscriptions != null) {
|
|
166
166
|
this._styleSubscriptions.dispose();
|
|
167
167
|
this._styleSubscriptions = null;
|
|
@@ -169,16 +169,16 @@ class NesquickComponent {
|
|
|
169
169
|
switch (typeof style) {
|
|
170
170
|
case "object": {
|
|
171
171
|
if (style) {
|
|
172
|
-
if (
|
|
172
|
+
if (lastReaction) {
|
|
173
|
+
this._renderStyles(element, style);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
173
176
|
element.removeAttribute("style");
|
|
174
177
|
this._styleSubscriptions = new State_1.Subscriptions();
|
|
175
178
|
State_1.subscriptions.set(this._styleSubscriptions);
|
|
176
179
|
this._renderStyles(element, style);
|
|
177
180
|
State_1.subscriptions.reset();
|
|
178
181
|
}
|
|
179
|
-
else {
|
|
180
|
-
this._renderStyles(element, style);
|
|
181
|
-
}
|
|
182
182
|
}
|
|
183
183
|
break;
|
|
184
184
|
}
|
package/lib/State.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.subscriptions = exports.Subscriptions = void 0;
|
|
|
4
4
|
exports.useState = useState;
|
|
5
5
|
exports.useEffect = useEffect;
|
|
6
6
|
exports.useRender = useRender;
|
|
7
|
+
exports.useMemo = useMemo;
|
|
7
8
|
exports.useDispose = useDispose;
|
|
8
9
|
let currentReactor = [];
|
|
9
10
|
var reactor;
|
|
@@ -87,18 +88,57 @@ function useState(value) {
|
|
|
87
88
|
return value;
|
|
88
89
|
};
|
|
89
90
|
const setValue = (newValue) => {
|
|
90
|
-
value
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
if (value !== newValue) {
|
|
92
|
+
value = newValue;
|
|
93
|
+
for (const reactor of reactors) {
|
|
94
|
+
renderReactor(reactor, reactor.effect);
|
|
95
|
+
}
|
|
93
96
|
}
|
|
94
97
|
};
|
|
95
98
|
return [getValue, setValue];
|
|
96
99
|
}
|
|
97
100
|
function useEffect(cb, reaction = null) {
|
|
98
|
-
newSubscription(cb, reaction, true);
|
|
101
|
+
const sub = newSubscription(cb, reaction, true);
|
|
102
|
+
runSubscription(sub);
|
|
99
103
|
}
|
|
100
104
|
function useRender(cb, reaction = null) {
|
|
101
|
-
newSubscription(cb, reaction, false);
|
|
105
|
+
const sub = newSubscription(cb, reaction, false);
|
|
106
|
+
runSubscription(sub);
|
|
107
|
+
}
|
|
108
|
+
function useMemo(cb) {
|
|
109
|
+
const reactors = new Set();
|
|
110
|
+
let state = 0;
|
|
111
|
+
let value;
|
|
112
|
+
const sub = newSubscription(() => {
|
|
113
|
+
if (state === 0) {
|
|
114
|
+
sub.iteration--;
|
|
115
|
+
}
|
|
116
|
+
else if (state === 1) {
|
|
117
|
+
state = 2;
|
|
118
|
+
value = cb();
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
sub.iteration--;
|
|
122
|
+
state = 0;
|
|
123
|
+
for (const reactor of reactors) {
|
|
124
|
+
renderReactor(reactor, reactor.effect);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}, null, true);
|
|
128
|
+
return () => {
|
|
129
|
+
if (state === 0) {
|
|
130
|
+
state = 1;
|
|
131
|
+
runSubscription(sub);
|
|
132
|
+
}
|
|
133
|
+
if (!sub.cancelled) {
|
|
134
|
+
const reactor = currentReactor[currentReactor.length - 1];
|
|
135
|
+
if (reactor) {
|
|
136
|
+
reactors.add(reactor);
|
|
137
|
+
reactor.states.set(reactors, reactor.iteration);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return value;
|
|
141
|
+
};
|
|
102
142
|
}
|
|
103
143
|
function useDispose(cb) {
|
|
104
144
|
const container = currentSubscriptions[currentSubscriptions.length - 1];
|
|
@@ -107,8 +147,10 @@ function useDispose(cb) {
|
|
|
107
147
|
}
|
|
108
148
|
}
|
|
109
149
|
function newSubscription(cb, reaction, effect) {
|
|
110
|
-
|
|
150
|
+
return {
|
|
111
151
|
cb: cb,
|
|
152
|
+
firstRun: true,
|
|
153
|
+
lastValue: null,
|
|
112
154
|
reaction: reaction,
|
|
113
155
|
iteration: 0,
|
|
114
156
|
states: new Map(),
|
|
@@ -117,16 +159,6 @@ function newSubscription(cb, reaction, effect) {
|
|
|
117
159
|
cancelled: false,
|
|
118
160
|
pending: false
|
|
119
161
|
};
|
|
120
|
-
renderReactor(sub, true);
|
|
121
|
-
if (sub.states.size === 0) {
|
|
122
|
-
cancelSubscription(sub);
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
const container = currentSubscriptions[currentSubscriptions.length - 1];
|
|
126
|
-
if (container) {
|
|
127
|
-
container.list.push(sub);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
162
|
}
|
|
131
163
|
function cancelSubscription(sub) {
|
|
132
164
|
sub.cancelled = true;
|
|
@@ -136,6 +168,7 @@ function cancelSubscription(sub) {
|
|
|
136
168
|
}
|
|
137
169
|
function runSubscription(sub) {
|
|
138
170
|
sub.pending = false;
|
|
171
|
+
sub.iteration++;
|
|
139
172
|
reactor.set(sub);
|
|
140
173
|
const res = sub.cb();
|
|
141
174
|
reactor.reset();
|
|
@@ -144,5 +177,24 @@ function runSubscription(sub) {
|
|
|
144
177
|
sub.states.delete(state);
|
|
145
178
|
}
|
|
146
179
|
}
|
|
147
|
-
|
|
180
|
+
if (sub.states.size === 0) {
|
|
181
|
+
cancelSubscription(sub);
|
|
182
|
+
}
|
|
183
|
+
if (sub.firstRun) {
|
|
184
|
+
sub.firstRun = false;
|
|
185
|
+
if (sub.states.size > 0) {
|
|
186
|
+
const container = currentSubscriptions[currentSubscriptions.length - 1];
|
|
187
|
+
if (container) {
|
|
188
|
+
container.list.push(sub);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (sub.reaction) {
|
|
192
|
+
sub.lastValue = res;
|
|
193
|
+
sub.reaction(res, sub.cancelled);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
else if (sub.reaction && sub.lastValue !== res) {
|
|
197
|
+
sub.lastValue = res;
|
|
198
|
+
sub.reaction(res, sub.cancelled);
|
|
199
|
+
}
|
|
148
200
|
}
|
package/lib/cli/transformer.js
CHANGED
|
@@ -24,60 +24,121 @@ function getSingleBody(node) {
|
|
|
24
24
|
}
|
|
25
25
|
return null;
|
|
26
26
|
}
|
|
27
|
-
function hasIdentifier(node) {
|
|
28
|
-
let found = false;
|
|
29
|
-
node.forEachChild(node => {
|
|
30
|
-
if (!found && (TS.isIdentifier(node) || hasIdentifier(node))) {
|
|
31
|
-
found = true;
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
return found;
|
|
35
|
-
}
|
|
36
27
|
const transformer = context => {
|
|
37
28
|
return sourceFile => {
|
|
38
29
|
const visitGeneric = (node, options) => {
|
|
30
|
+
let hasSpread = options.userComponent && TS.isJsxSpreadAttribute(node);
|
|
31
|
+
let hasChildIdentifier = false;
|
|
39
32
|
if (TS.isJsxOpeningLikeElement(node)) {
|
|
40
33
|
const firstLetter = node.tagName.getText()[0];
|
|
41
34
|
const userComponent = firstLetter !== firstLetter.toLowerCase();
|
|
42
|
-
|
|
35
|
+
node = TS.visitEachChild(node, node => {
|
|
36
|
+
const res = visitGeneric(node, { userComponent });
|
|
37
|
+
hasSpread = hasSpread || res.hasSpread;
|
|
38
|
+
hasChildIdentifier = hasChildIdentifier || res.hasChildIdentifier || TS.isIdentifier(node);
|
|
39
|
+
return res.node;
|
|
40
|
+
}, context);
|
|
41
|
+
if (userComponent && hasSpread) {
|
|
42
|
+
const symbol = TS.factory.createCallExpression(TS.factory.createPropertyAccessExpression(TS.factory.createIdentifier("Symbol"), "for"), void 0, [TS.factory.createStringLiteral("$nesquickSpreadProps")]);
|
|
43
|
+
if (TS.isJsxOpeningLikeElement(node)) {
|
|
44
|
+
const attributes = TS.factory.updateJsxAttributes(node.attributes, [
|
|
45
|
+
...node.attributes.properties,
|
|
46
|
+
TS.factory.createJsxSpreadAttribute(TS.factory.createObjectLiteralExpression([
|
|
47
|
+
TS.factory.createPropertyAssignment(TS.factory.createComputedPropertyName(symbol), TS.factory.createTrue())
|
|
48
|
+
]))
|
|
49
|
+
]);
|
|
50
|
+
if (TS.isJsxOpeningElement(node)) {
|
|
51
|
+
node = TS.factory.updateJsxOpeningElement(node, node.tagName, node.typeArguments, attributes);
|
|
52
|
+
}
|
|
53
|
+
else if (TS.isJsxSelfClosingElement(node)) {
|
|
54
|
+
node = TS.factory.updateJsxSelfClosingElement(node, node.tagName, node.typeArguments, attributes);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
43
58
|
}
|
|
44
|
-
if (TS.isJsxAttribute(node)) {
|
|
45
|
-
|
|
59
|
+
else if (TS.isJsxAttribute(node)) {
|
|
60
|
+
node = TS.visitEachChild(node, node => {
|
|
61
|
+
const res = visitGeneric(node, { ...options, isJsxAttribute: true });
|
|
62
|
+
hasSpread = hasSpread || res.hasSpread;
|
|
63
|
+
hasChildIdentifier = hasChildIdentifier || res.hasChildIdentifier || TS.isIdentifier(node);
|
|
64
|
+
return res.node;
|
|
65
|
+
}, context);
|
|
46
66
|
}
|
|
47
67
|
else if (TS.isJsxExpression(node)) {
|
|
48
|
-
|
|
68
|
+
node = TS.visitEachChild(node, node => {
|
|
69
|
+
const res = visitorExpression(node, { ...options, isJsxAttribute: false });
|
|
70
|
+
hasChildIdentifier = hasChildIdentifier || res.hasChildIdentifier || TS.isIdentifier(node);
|
|
71
|
+
return res.node;
|
|
72
|
+
}, context);
|
|
49
73
|
}
|
|
50
74
|
else if (options.isJsxAttribute && TS.isStringLiteral(node)) {
|
|
51
|
-
const returnNode = TS.visitNode(node, node =>
|
|
52
|
-
|
|
53
|
-
|
|
75
|
+
const returnNode = TS.visitNode(node, node => {
|
|
76
|
+
const res = visitorExpression(node, { ...options, isJsxAttribute: false });
|
|
77
|
+
hasChildIdentifier = hasChildIdentifier || res.hasChildIdentifier || TS.isIdentifier(node);
|
|
78
|
+
return res.node;
|
|
79
|
+
}, TS.isExpression);
|
|
80
|
+
if (TS.isStringLiteral(returnNode)) {
|
|
81
|
+
node = returnNode;
|
|
54
82
|
}
|
|
55
|
-
|
|
83
|
+
else {
|
|
84
|
+
node = TS.factory.createJsxExpression(undefined, returnNode);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
node = TS.visitEachChild(node, node => {
|
|
89
|
+
const res = visitGeneric(node, { ...options, isJsxAttribute: false });
|
|
90
|
+
hasSpread = hasSpread || res.hasSpread;
|
|
91
|
+
hasChildIdentifier = hasChildIdentifier || res.hasChildIdentifier || TS.isIdentifier(node);
|
|
92
|
+
return res.node;
|
|
93
|
+
}, context);
|
|
56
94
|
}
|
|
57
|
-
return
|
|
95
|
+
return { hasSpread, hasChildIdentifier, node };
|
|
58
96
|
};
|
|
59
97
|
const visitorExpression = (node, options) => {
|
|
98
|
+
let hasChildIdentifier = false;
|
|
60
99
|
if (TS.isParenthesizedExpression(node)) {
|
|
61
100
|
const body = getSingleBody(node);
|
|
62
101
|
if (body) {
|
|
63
|
-
|
|
102
|
+
node = TS.visitNode(body, node => {
|
|
103
|
+
const res = visitorExpression(node, options);
|
|
104
|
+
hasChildIdentifier = hasChildIdentifier || res.hasChildIdentifier || TS.isIdentifier(node);
|
|
105
|
+
return res.node;
|
|
106
|
+
});
|
|
64
107
|
}
|
|
65
108
|
}
|
|
66
109
|
else if (TS.isCallExpression(node)) {
|
|
67
110
|
const identifier = getSingleIdentifier(node);
|
|
68
111
|
if (identifier) {
|
|
69
|
-
|
|
112
|
+
node = identifier;
|
|
70
113
|
}
|
|
71
114
|
else {
|
|
72
|
-
|
|
115
|
+
node = TS.factory.createArrowFunction(undefined, undefined, [], undefined, TS.factory.createToken(TS.SyntaxKind.EqualsGreaterThanToken), TS.visitNode(node, node => {
|
|
116
|
+
const res = visitGeneric(node, {});
|
|
117
|
+
hasChildIdentifier = hasChildIdentifier || res.hasChildIdentifier || TS.isIdentifier(node);
|
|
118
|
+
return res.node;
|
|
119
|
+
}, TS.isConciseBody));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else if (!TS.isFunctionLike(node) && TS.isExpression(node)) {
|
|
123
|
+
node = TS.visitNode(node, node => {
|
|
124
|
+
const res = visitGeneric(node, {});
|
|
125
|
+
hasChildIdentifier = hasChildIdentifier || res.hasChildIdentifier;
|
|
126
|
+
return res.node;
|
|
127
|
+
});
|
|
128
|
+
if ((options.userComponent || hasChildIdentifier) && TS.isConciseBody(node)) {
|
|
129
|
+
node = TS.factory.createArrowFunction(undefined, undefined, [], undefined, TS.factory.createToken(TS.SyntaxKind.EqualsGreaterThanToken), node);
|
|
73
130
|
}
|
|
74
131
|
}
|
|
75
|
-
else
|
|
76
|
-
|
|
132
|
+
else {
|
|
133
|
+
node = TS.visitNode(node, node => {
|
|
134
|
+
const res = visitGeneric(node, {});
|
|
135
|
+
hasChildIdentifier = hasChildIdentifier || res.hasChildIdentifier || TS.isIdentifier(node);
|
|
136
|
+
return res.node;
|
|
137
|
+
});
|
|
77
138
|
}
|
|
78
|
-
return
|
|
139
|
+
return { hasChildIdentifier, node };
|
|
79
140
|
};
|
|
80
|
-
return TS.visitNode(sourceFile, node => visitGeneric(node, {}), TS.isSourceFile);
|
|
141
|
+
return TS.visitNode(sourceFile, node => visitGeneric(node, {}).node, TS.isSourceFile);
|
|
81
142
|
};
|
|
82
143
|
};
|
|
83
144
|
exports.transformer = transformer;
|
package/lib/jsx-runtime.js
CHANGED
|
@@ -4,11 +4,16 @@ exports.JSX = exports.jsx = exports.Fragment = void 0;
|
|
|
4
4
|
exports.jsxs = jsxs;
|
|
5
5
|
const NesquickComponent_1 = require("./NesquickComponent");
|
|
6
6
|
const NesquickFragment_1 = require("./NesquickFragment");
|
|
7
|
+
const jsx_runtime_1 = require("./no-transformer/jsx-runtime");
|
|
8
|
+
const propsSpreadSymbol = Symbol.for("$nesquickSpreadProps");
|
|
7
9
|
exports.Fragment = Symbol();
|
|
8
10
|
function jsxs(type, props, key) {
|
|
9
11
|
if (type === exports.Fragment) {
|
|
10
12
|
return new NesquickFragment_1.NesquickFragment(props.children);
|
|
11
13
|
}
|
|
14
|
+
if (props[propsSpreadSymbol]) {
|
|
15
|
+
(0, jsx_runtime_1.functionizeProps)(props);
|
|
16
|
+
}
|
|
12
17
|
if (key !== undefined) {
|
|
13
18
|
props.key = key;
|
|
14
19
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.JSX = exports.jsx = exports.Fragment = void 0;
|
|
4
|
+
exports.functionizeProps = functionizeProps;
|
|
4
5
|
exports.jsxs = jsxs;
|
|
5
6
|
const NesquickComponent_1 = require("../NesquickComponent");
|
|
6
7
|
const NesquickFragment_1 = require("../NesquickFragment");
|
package/lib/types/State.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
export type
|
|
2
|
-
export type
|
|
1
|
+
export type Getter<T> = () => T;
|
|
2
|
+
export type Setter<T> = (value: T) => void;
|
|
3
|
+
export type State<T> = [get: Getter<T>, set: Setter<T>];
|
|
4
|
+
type Subscription<T> = {
|
|
3
5
|
cb: () => T;
|
|
4
|
-
reaction: ((data: T, isState: boolean) => void) | null;
|
|
5
6
|
iteration: number;
|
|
7
|
+
lastValue: T | null;
|
|
8
|
+
firstRun: boolean;
|
|
9
|
+
reaction: ((data: T, lastReaction: boolean) => void) | null;
|
|
6
10
|
states: Map<Set<Subscription<any>>, number>;
|
|
7
11
|
next: Subscription<T> | null;
|
|
8
12
|
effect: boolean;
|
|
@@ -19,6 +23,8 @@ export declare namespace subscriptions {
|
|
|
19
23
|
function reset(): void;
|
|
20
24
|
}
|
|
21
25
|
export declare function useState<T>(value: T): State<T>;
|
|
22
|
-
export declare function useEffect<T>(cb: () => T, reaction?: ((data: T,
|
|
23
|
-
export declare function useRender<T>(cb: () => T, reaction?: ((data: T,
|
|
26
|
+
export declare function useEffect<T>(cb: () => T, reaction?: ((data: T, lastReaction: boolean) => void) | null): void;
|
|
27
|
+
export declare function useRender<T>(cb: () => T, reaction?: ((data: T, lastReaction: boolean) => void) | null): void;
|
|
28
|
+
export declare function useMemo<T>(cb: () => T): Getter<T>;
|
|
24
29
|
export declare function useDispose(cb: () => void): void;
|
|
30
|
+
export {};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { FunctionComponent, ComponentProps, NesquickComponent } from "./NesquickComponent";
|
|
2
2
|
import { NesquickFragment } from "./NesquickFragment";
|
|
3
|
+
declare const propsSpreadSymbol: unique symbol;
|
|
3
4
|
export declare const Fragment: unique symbol;
|
|
4
|
-
export declare function jsxs<P extends ComponentProps
|
|
5
|
+
export declare function jsxs<P extends ComponentProps & {
|
|
6
|
+
[propsSpreadSymbol]?: true;
|
|
7
|
+
}>(type: string | FunctionComponent<P> | typeof Fragment, props: P, key?: string | number | null): NesquickFragment | NesquickComponent<P>;
|
|
5
8
|
export declare const jsx: typeof jsxs;
|
|
6
9
|
type HasUndefined<T, K extends keyof T> = {
|
|
7
10
|
[L in K]-?: T[K] | undefined;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { FunctionComponent, ComponentProps, NesquickComponent } from "../NesquickComponent";
|
|
2
2
|
import { NesquickFragment } from "../NesquickFragment";
|
|
3
3
|
export declare const Fragment: unique symbol;
|
|
4
|
+
export declare function functionizeProps(props: ComponentProps): void;
|
|
4
5
|
export declare function jsxs<P extends ComponentProps>(type: string | FunctionComponent<P> | typeof Fragment, props: P, key?: string | number | null): NesquickFragment | NesquickComponent<P>;
|
|
5
6
|
export declare const jsx: typeof jsxs;
|
|
6
7
|
type HasUndefined<T, K extends keyof T> = {
|