solid-js 1.1.6-beta.0 → 1.2.0-beta.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/README.md +2 -4
- package/dist/dev.cjs +145 -147
- package/dist/dev.js +145 -147
- package/dist/solid.cjs +143 -145
- package/dist/solid.js +143 -145
- package/html/dist/html.cjs +24 -6
- package/html/dist/html.js +25 -7
- package/package.json +14 -2
- package/types/jsx.d.ts +2 -1
- package/types/reactive/signal.d.ts +13 -8
- package/types/render/component.d.ts +1 -1
- package/universal/dist/dev.cjs +258 -0
- package/universal/dist/dev.js +254 -0
- package/universal/dist/universal.cjs +258 -0
- package/universal/dist/universal.js +254 -0
- package/universal/package.json +8 -0
- package/universal/types/index.d.ts +2 -0
- package/universal/types/universal.d.ts +29 -0
- package/web/types/client.d.ts +1 -1
- package/types/reactive/signal noarray.d.ts +0 -429
- package/types/reactive/signal option.d.ts +0 -178
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "solid-js",
|
|
3
3
|
"description": "A declarative JavaScript library for building user interfaces.",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.2.0-beta.0",
|
|
5
5
|
"author": "Ryan Carniato",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://github.com/solidjs/solid#readme",
|
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
"h/types",
|
|
30
30
|
"html/dist",
|
|
31
31
|
"html/types",
|
|
32
|
+
"universal/dist",
|
|
33
|
+
"universal/types",
|
|
32
34
|
"types",
|
|
33
35
|
"jsx-runtime.d.ts"
|
|
34
36
|
],
|
|
@@ -84,6 +86,15 @@
|
|
|
84
86
|
"require": "./web/dist/web.cjs"
|
|
85
87
|
},
|
|
86
88
|
"./web/dist/*": "./web/dist/*",
|
|
89
|
+
"./universal": {
|
|
90
|
+
"development": {
|
|
91
|
+
"import": "./universal/dist/dev.js",
|
|
92
|
+
"require": "./universal/dist/dev.cjs"
|
|
93
|
+
},
|
|
94
|
+
"import": "./universal/dist/universal.js",
|
|
95
|
+
"require": "./universal/dist/universal.cjs"
|
|
96
|
+
},
|
|
97
|
+
"./universal/dist/*": "./universal/dist/*",
|
|
87
98
|
"./h": {
|
|
88
99
|
"import": "./h/dist/h.js",
|
|
89
100
|
"require": "./h/dist/h.cjs"
|
|
@@ -106,6 +117,7 @@
|
|
|
106
117
|
"build:types-web": "tsc --project ./web/tsconfig.json && tsconfig-replace-paths --project ./web/tsconfig.types.json",
|
|
107
118
|
"build:types-html": "tsc --project ./html/tsconfig.json",
|
|
108
119
|
"build:types-h": "tsc --project ./h/tsconfig.json",
|
|
120
|
+
"build:types-universal": "tsc --project ./universal/tsconfig.json",
|
|
109
121
|
"bench": "node --allow-natives-syntax bench/bench.cjs",
|
|
110
122
|
"test": "jest && npm run test:types",
|
|
111
123
|
"test:coverage": "jest --coverage && npm run test:types",
|
|
@@ -120,5 +132,5 @@
|
|
|
120
132
|
"compiler",
|
|
121
133
|
"performance"
|
|
122
134
|
],
|
|
123
|
-
"gitHead": "
|
|
135
|
+
"gitHead": "ec5bfa3adc09c0efd9210be6ff5096ec18c06d02"
|
|
124
136
|
}
|
package/types/jsx.d.ts
CHANGED
|
@@ -1674,6 +1674,7 @@ export namespace JSX {
|
|
|
1674
1674
|
| "unsafe-url";
|
|
1675
1675
|
type HTMLIframeSandbox =
|
|
1676
1676
|
| "allow-downloads-without-user-activation"
|
|
1677
|
+
| "allow-downloads"
|
|
1677
1678
|
| "allow-forms"
|
|
1678
1679
|
| "allow-modals"
|
|
1679
1680
|
| "allow-orientation-lock"
|
|
@@ -2116,7 +2117,7 @@ export namespace JSX {
|
|
|
2116
2117
|
height?: number | string;
|
|
2117
2118
|
name?: string;
|
|
2118
2119
|
referrerpolicy?: HTMLReferrerPolicy;
|
|
2119
|
-
sandbox?: HTMLIframeSandbox;
|
|
2120
|
+
sandbox?: HTMLIframeSandbox | string;
|
|
2120
2121
|
src?: string;
|
|
2121
2122
|
srcdoc?: string;
|
|
2122
2123
|
width?: number | string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { requestCallback } from "./scheduler";
|
|
2
2
|
import type { JSX } from "../jsx";
|
|
3
3
|
export declare type Accessor<T> = () => T;
|
|
4
|
-
export declare type Setter<T> = undefined extends T ? <U extends T>(v?: (U extends Function ? never : U) | ((prev?:
|
|
4
|
+
export declare type Setter<T> = undefined extends T ? <U extends T>(v?: (U extends Function ? never : U) | ((prev?: T) => U)) => U : <U extends T>(v: (U extends Function ? never : U) | ((prev: T) => U)) => U;
|
|
5
5
|
export declare const equalFn: <T>(a: T, b: T) => boolean;
|
|
6
6
|
export declare const $PROXY: unique symbol;
|
|
7
7
|
export declare const NOTPENDING: {};
|
|
@@ -15,6 +15,7 @@ interface Signal<T> {
|
|
|
15
15
|
observers: Computation<any>[] | null;
|
|
16
16
|
observerSlots: number[] | null;
|
|
17
17
|
pending: T | {};
|
|
18
|
+
tValue?: T;
|
|
18
19
|
comparator?: (prev: T, next: T) => boolean;
|
|
19
20
|
name?: string;
|
|
20
21
|
}
|
|
@@ -32,20 +33,23 @@ interface Owner {
|
|
|
32
33
|
interface Computation<T> extends Owner {
|
|
33
34
|
fn: (v?: T) => T;
|
|
34
35
|
state: number;
|
|
36
|
+
tState?: number;
|
|
35
37
|
sources: Signal<T>[] | null;
|
|
36
38
|
sourceSlots: number[] | null;
|
|
37
39
|
value?: T;
|
|
38
|
-
updatedAt: number;
|
|
40
|
+
updatedAt: number | null;
|
|
39
41
|
pure: boolean;
|
|
40
42
|
user?: boolean;
|
|
41
43
|
suspense?: SuspenseContextType;
|
|
42
44
|
}
|
|
45
|
+
interface Memo<T> extends Signal<T>, Computation<T> {
|
|
46
|
+
tOwned?: Computation<any>[];
|
|
47
|
+
}
|
|
43
48
|
interface Transition {
|
|
44
|
-
sources: Set<Signal<any
|
|
45
|
-
lookup: Map<Signal<any> | Computation<any>, Signal<any> | Computation<any>>;
|
|
46
|
-
updated: Set<Computation<any>>;
|
|
49
|
+
sources: Set<Signal<any>>;
|
|
47
50
|
effects: Computation<any>[];
|
|
48
51
|
promises: Set<Promise<any>>;
|
|
52
|
+
disposed: Set<Computation<any>>;
|
|
49
53
|
queue: Set<Computation<any>>;
|
|
50
54
|
scheduler?: (fn: () => void) => unknown;
|
|
51
55
|
running: boolean;
|
|
@@ -244,7 +248,7 @@ export declare function createDeferred<T>(source: Accessor<T>, options?: {
|
|
|
244
248
|
/**
|
|
245
249
|
* Creates a conditional signal that only notifies subscribers when entering or exiting their key matching the value
|
|
246
250
|
* ```typescript
|
|
247
|
-
* export function
|
|
251
|
+
* export function createSelector<T, U>(
|
|
248
252
|
* source: () => T
|
|
249
253
|
* fn: (a: U, b: T) => boolean,
|
|
250
254
|
* options?: { name?: string }
|
|
@@ -263,7 +267,7 @@ export declare function createDeferred<T>(source: Accessor<T>, options?: {
|
|
|
263
267
|
*
|
|
264
268
|
* This makes the operation O(2) instead of O(n).
|
|
265
269
|
*
|
|
266
|
-
* @description https://www.solidjs.com/docs/latest/api#
|
|
270
|
+
* @description https://www.solidjs.com/docs/latest/api#createselector
|
|
267
271
|
*/
|
|
268
272
|
export declare function createSelector<T, U>(source: Accessor<T>, fn?: (a: U, b: T) => boolean, options?: {
|
|
269
273
|
name?: string;
|
|
@@ -421,5 +425,6 @@ export declare function getSuspenseContext(): Context<SuspenseContextType> & {
|
|
|
421
425
|
increment?(): void;
|
|
422
426
|
decrement?(): void;
|
|
423
427
|
};
|
|
424
|
-
export declare function
|
|
428
|
+
export declare function readSignal(this: Signal<any> | Memo<any>): any;
|
|
429
|
+
export declare function writeSignal(node: Signal<any> | Memo<any>, value: any, isComp?: boolean): any;
|
|
425
430
|
export {};
|
|
@@ -15,7 +15,7 @@ export declare function createComponent<T>(Comp: (props: T) => JSX.Element, prop
|
|
|
15
15
|
declare type BoxedTupleTypes<T extends any[]> = {
|
|
16
16
|
[P in keyof T]: [T[P]];
|
|
17
17
|
}[Exclude<keyof T, keyof any[]>];
|
|
18
|
-
declare type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
|
|
18
|
+
declare type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
19
19
|
declare type UnboxIntersection<T> = T extends {
|
|
20
20
|
0: infer U;
|
|
21
21
|
} ? U : never;
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var solidJs = require('solid-js');
|
|
6
|
+
|
|
7
|
+
function memo(fn, equals) {
|
|
8
|
+
return solidJs.createMemo(fn, undefined, !equals ? {
|
|
9
|
+
equals
|
|
10
|
+
} : undefined);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function createRenderer$1({
|
|
14
|
+
createElement,
|
|
15
|
+
createTextNode,
|
|
16
|
+
isTextNode,
|
|
17
|
+
replaceText,
|
|
18
|
+
insertNode,
|
|
19
|
+
removeNode,
|
|
20
|
+
setProperty,
|
|
21
|
+
getParentNode,
|
|
22
|
+
getFirstChild,
|
|
23
|
+
getNextSibling
|
|
24
|
+
}) {
|
|
25
|
+
function insert(parent, accessor, marker, initial) {
|
|
26
|
+
if (marker !== undefined && !initial) initial = [];
|
|
27
|
+
if (typeof accessor !== "function") return insertExpression(parent, accessor, initial, marker);
|
|
28
|
+
solidJs.createRenderEffect(current => insertExpression(parent, accessor(), current, marker), initial);
|
|
29
|
+
}
|
|
30
|
+
function insertExpression(parent, value, current, marker, unwrapArray) {
|
|
31
|
+
while (typeof current === "function") current = current();
|
|
32
|
+
if (value === current) return current;
|
|
33
|
+
const t = typeof value,
|
|
34
|
+
multi = marker !== undefined;
|
|
35
|
+
if (t === "string" || t === "number") {
|
|
36
|
+
if (t === "number") value = value.toString();
|
|
37
|
+
if (multi) {
|
|
38
|
+
let node = current[0];
|
|
39
|
+
if (node && isTextNode(node)) {
|
|
40
|
+
replaceText(node, value);
|
|
41
|
+
} else node = createTextNode(value);
|
|
42
|
+
current = cleanChildren(parent, current, marker, node);
|
|
43
|
+
} else {
|
|
44
|
+
if (current !== "" && typeof current === "string") {
|
|
45
|
+
replaceText(getFirstChild(parent), current = value);
|
|
46
|
+
} else {
|
|
47
|
+
cleanChildren(parent, current, marker, createTextNode(value));
|
|
48
|
+
current = value;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
} else if (value == null || t === "boolean") {
|
|
52
|
+
current = cleanChildren(parent, current, marker);
|
|
53
|
+
} else if (t === "function") {
|
|
54
|
+
solidJs.createRenderEffect(() => {
|
|
55
|
+
let v = value();
|
|
56
|
+
while (typeof v === "function") v = v();
|
|
57
|
+
current = insertExpression(parent, v, current, marker);
|
|
58
|
+
});
|
|
59
|
+
return () => current;
|
|
60
|
+
} else if (Array.isArray(value)) {
|
|
61
|
+
const array = [];
|
|
62
|
+
if (normalizeIncomingArray(array, value, unwrapArray)) {
|
|
63
|
+
solidJs.createRenderEffect(() => current = insertExpression(parent, array, current, marker, true));
|
|
64
|
+
return () => current;
|
|
65
|
+
}
|
|
66
|
+
if (array.length === 0) {
|
|
67
|
+
const replacement = cleanChildren(parent, current, marker);
|
|
68
|
+
if (multi) return current = replacement;
|
|
69
|
+
} else {
|
|
70
|
+
if (Array.isArray(current)) {
|
|
71
|
+
if (current.length === 0) {
|
|
72
|
+
appendNodes(parent, array, marker);
|
|
73
|
+
} else reconcileArrays(parent, current, array);
|
|
74
|
+
} else if (current == null || current === "") {
|
|
75
|
+
appendNodes(parent, array);
|
|
76
|
+
} else {
|
|
77
|
+
reconcileArrays(parent, multi && current || [getFirstChild(parent)], array);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
current = array;
|
|
81
|
+
} else {
|
|
82
|
+
if (Array.isArray(current)) {
|
|
83
|
+
if (multi) return current = cleanChildren(parent, current, marker, value);
|
|
84
|
+
cleanChildren(parent, current, null, value);
|
|
85
|
+
} else if (current == null || current === "" || !getFirstChild(parent)) {
|
|
86
|
+
insertNode(parent, value);
|
|
87
|
+
} else replaceNode(parent, value, getFirstChild(parent));
|
|
88
|
+
current = value;
|
|
89
|
+
}
|
|
90
|
+
return current;
|
|
91
|
+
}
|
|
92
|
+
function normalizeIncomingArray(normalized, array, unwrap) {
|
|
93
|
+
let dynamic = false;
|
|
94
|
+
for (let i = 0, len = array.length; i < len; i++) {
|
|
95
|
+
let item = array[i],
|
|
96
|
+
t;
|
|
97
|
+
if (item == null || item === true || item === false) ; else if (Array.isArray(item)) {
|
|
98
|
+
dynamic = normalizeIncomingArray(normalized, item) || dynamic;
|
|
99
|
+
} else if ((t = typeof item) === "string" || t === "number") {
|
|
100
|
+
normalized.push(createTextNode(item));
|
|
101
|
+
} else if (t === "function") {
|
|
102
|
+
if (unwrap) {
|
|
103
|
+
while (typeof item === "function") item = item();
|
|
104
|
+
dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item]) || dynamic;
|
|
105
|
+
} else {
|
|
106
|
+
normalized.push(item);
|
|
107
|
+
dynamic = true;
|
|
108
|
+
}
|
|
109
|
+
} else normalized.push(item);
|
|
110
|
+
}
|
|
111
|
+
return dynamic;
|
|
112
|
+
}
|
|
113
|
+
function reconcileArrays(parentNode, a, b) {
|
|
114
|
+
let bLength = b.length,
|
|
115
|
+
aEnd = a.length,
|
|
116
|
+
bEnd = bLength,
|
|
117
|
+
aStart = 0,
|
|
118
|
+
bStart = 0,
|
|
119
|
+
after = getNextSibling(a[aEnd - 1]),
|
|
120
|
+
map = null;
|
|
121
|
+
while (aStart < aEnd || bStart < bEnd) {
|
|
122
|
+
if (a[aStart] === b[bStart]) {
|
|
123
|
+
aStart++;
|
|
124
|
+
bStart++;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
while (a[aEnd - 1] === b[bEnd - 1]) {
|
|
128
|
+
aEnd--;
|
|
129
|
+
bEnd--;
|
|
130
|
+
}
|
|
131
|
+
if (aEnd === aStart) {
|
|
132
|
+
const node = bEnd < bLength ? bStart ? getNextSibling(b[bStart - 1]) : b[bEnd - bStart] : after;
|
|
133
|
+
while (bStart < bEnd) insertNode(parentNode, b[bStart++], node);
|
|
134
|
+
} else if (bEnd === bStart) {
|
|
135
|
+
while (aStart < aEnd) {
|
|
136
|
+
if (!map || !map.has(a[aStart])) removeNode(parentNode, a[aStart]);
|
|
137
|
+
aStart++;
|
|
138
|
+
}
|
|
139
|
+
} else if (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]) {
|
|
140
|
+
const node = getNextSibling(a[--aEnd]);
|
|
141
|
+
insertNode(parentNode, b[bStart++], getNextSibling(a[aStart++]));
|
|
142
|
+
insertNode(parentNode, b[--bEnd], node);
|
|
143
|
+
a[aEnd] = b[bEnd];
|
|
144
|
+
} else {
|
|
145
|
+
if (!map) {
|
|
146
|
+
map = new Map();
|
|
147
|
+
let i = bStart;
|
|
148
|
+
while (i < bEnd) map.set(b[i], i++);
|
|
149
|
+
}
|
|
150
|
+
const index = map.get(a[aStart]);
|
|
151
|
+
if (index != null) {
|
|
152
|
+
if (bStart < index && index < bEnd) {
|
|
153
|
+
let i = aStart,
|
|
154
|
+
sequence = 1,
|
|
155
|
+
t;
|
|
156
|
+
while (++i < aEnd && i < bEnd) {
|
|
157
|
+
if ((t = map.get(a[i])) == null || t !== index + sequence) break;
|
|
158
|
+
sequence++;
|
|
159
|
+
}
|
|
160
|
+
if (sequence > index - bStart) {
|
|
161
|
+
const node = a[aStart];
|
|
162
|
+
while (bStart < index) insertNode(parentNode, b[bStart++], node);
|
|
163
|
+
} else replaceNode(parentNode, b[bStart++], a[aStart++]);
|
|
164
|
+
} else aStart++;
|
|
165
|
+
} else removeNode(parentNode, a[aStart++]);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function cleanChildren(parent, current, marker, replacement) {
|
|
170
|
+
if (marker === undefined) {
|
|
171
|
+
let removed;
|
|
172
|
+
while (removed = getFirstChild(parent)) removeNode(parent, removed);
|
|
173
|
+
replacement && insertNode(parent, replacement);
|
|
174
|
+
return "";
|
|
175
|
+
}
|
|
176
|
+
const node = replacement || createTextNode("");
|
|
177
|
+
if (current.length) {
|
|
178
|
+
let inserted = false;
|
|
179
|
+
for (let i = current.length - 1; i >= 0; i--) {
|
|
180
|
+
const el = current[i];
|
|
181
|
+
if (node !== el) {
|
|
182
|
+
const isParent = getParentNode(el) === parent;
|
|
183
|
+
if (!inserted && !i) isParent ? replaceNode(parent, node, el) : insertNode(parent, node, marker);else isParent && removeNode(parent, el);
|
|
184
|
+
} else inserted = true;
|
|
185
|
+
}
|
|
186
|
+
} else insertNode(parent, node, marker);
|
|
187
|
+
return [node];
|
|
188
|
+
}
|
|
189
|
+
function appendNodes(parent, array, marker) {
|
|
190
|
+
for (let i = 0, len = array.length; i < len; i++) insertNode(parent, array[i], marker);
|
|
191
|
+
}
|
|
192
|
+
function replaceNode(parent, newNode, oldNode) {
|
|
193
|
+
insertNode(parent, newNode, oldNode);
|
|
194
|
+
removeNode(parent, oldNode);
|
|
195
|
+
}
|
|
196
|
+
function spreadExpression(node, props, prevProps = {}, skipChildren) {
|
|
197
|
+
if (!skipChildren && "children" in props) {
|
|
198
|
+
solidJs.createRenderEffect(() => prevProps.children = insertExpression(node, props.children, prevProps.children));
|
|
199
|
+
}
|
|
200
|
+
solidJs.createRenderEffect(() => {
|
|
201
|
+
for (const prop in props) {
|
|
202
|
+
if (prop === "children") continue;
|
|
203
|
+
const value = props[prop];
|
|
204
|
+
if (value === prevProps[prop]) continue;
|
|
205
|
+
if (prop === "ref") value(node);else {
|
|
206
|
+
setProperty(node, prop, value, prevProps[prop]);
|
|
207
|
+
prevProps[prop] = value;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
return prevProps;
|
|
212
|
+
}
|
|
213
|
+
return {
|
|
214
|
+
render(code, element) {
|
|
215
|
+
let disposer;
|
|
216
|
+
solidJs.createRoot(dispose => {
|
|
217
|
+
disposer = dispose;
|
|
218
|
+
insert(element, code());
|
|
219
|
+
});
|
|
220
|
+
return disposer;
|
|
221
|
+
},
|
|
222
|
+
insert,
|
|
223
|
+
spread(node, accessor, skipChildren) {
|
|
224
|
+
if (typeof accessor === "function") {
|
|
225
|
+
solidJs.createRenderEffect(current => spreadExpression(node, accessor(), current, skipChildren));
|
|
226
|
+
} else spreadExpression(node, accessor, undefined, skipChildren);
|
|
227
|
+
},
|
|
228
|
+
createElement,
|
|
229
|
+
createTextNode,
|
|
230
|
+
insertNode,
|
|
231
|
+
setProp(node, name, value, prev) {
|
|
232
|
+
setProperty(node, name, value, prev);
|
|
233
|
+
return value;
|
|
234
|
+
},
|
|
235
|
+
mergeProps,
|
|
236
|
+
effect: solidJs.createRenderEffect,
|
|
237
|
+
memo,
|
|
238
|
+
createComponent: solidJs.createComponent
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
function mergeProps(...sources) {
|
|
242
|
+
const target = {};
|
|
243
|
+
for (let i = 0; i < sources.length; i++) {
|
|
244
|
+
let source = sources[i];
|
|
245
|
+
if (typeof source === "function") source = source();
|
|
246
|
+
const descriptors = Object.getOwnPropertyDescriptors(source);
|
|
247
|
+
Object.defineProperties(target, descriptors);
|
|
248
|
+
}
|
|
249
|
+
return target;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function createRenderer(options) {
|
|
253
|
+
const renderer = createRenderer$1(options);
|
|
254
|
+
renderer.mergeProps = solidJs.mergeProps;
|
|
255
|
+
return renderer;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
exports.createRenderer = createRenderer;
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { createMemo, createRoot, createRenderEffect, createComponent, mergeProps as mergeProps$1 } from 'solid-js';
|
|
2
|
+
|
|
3
|
+
function memo(fn, equals) {
|
|
4
|
+
return createMemo(fn, undefined, !equals ? {
|
|
5
|
+
equals
|
|
6
|
+
} : undefined);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function createRenderer$1({
|
|
10
|
+
createElement,
|
|
11
|
+
createTextNode,
|
|
12
|
+
isTextNode,
|
|
13
|
+
replaceText,
|
|
14
|
+
insertNode,
|
|
15
|
+
removeNode,
|
|
16
|
+
setProperty,
|
|
17
|
+
getParentNode,
|
|
18
|
+
getFirstChild,
|
|
19
|
+
getNextSibling
|
|
20
|
+
}) {
|
|
21
|
+
function insert(parent, accessor, marker, initial) {
|
|
22
|
+
if (marker !== undefined && !initial) initial = [];
|
|
23
|
+
if (typeof accessor !== "function") return insertExpression(parent, accessor, initial, marker);
|
|
24
|
+
createRenderEffect(current => insertExpression(parent, accessor(), current, marker), initial);
|
|
25
|
+
}
|
|
26
|
+
function insertExpression(parent, value, current, marker, unwrapArray) {
|
|
27
|
+
while (typeof current === "function") current = current();
|
|
28
|
+
if (value === current) return current;
|
|
29
|
+
const t = typeof value,
|
|
30
|
+
multi = marker !== undefined;
|
|
31
|
+
if (t === "string" || t === "number") {
|
|
32
|
+
if (t === "number") value = value.toString();
|
|
33
|
+
if (multi) {
|
|
34
|
+
let node = current[0];
|
|
35
|
+
if (node && isTextNode(node)) {
|
|
36
|
+
replaceText(node, value);
|
|
37
|
+
} else node = createTextNode(value);
|
|
38
|
+
current = cleanChildren(parent, current, marker, node);
|
|
39
|
+
} else {
|
|
40
|
+
if (current !== "" && typeof current === "string") {
|
|
41
|
+
replaceText(getFirstChild(parent), current = value);
|
|
42
|
+
} else {
|
|
43
|
+
cleanChildren(parent, current, marker, createTextNode(value));
|
|
44
|
+
current = value;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
} else if (value == null || t === "boolean") {
|
|
48
|
+
current = cleanChildren(parent, current, marker);
|
|
49
|
+
} else if (t === "function") {
|
|
50
|
+
createRenderEffect(() => {
|
|
51
|
+
let v = value();
|
|
52
|
+
while (typeof v === "function") v = v();
|
|
53
|
+
current = insertExpression(parent, v, current, marker);
|
|
54
|
+
});
|
|
55
|
+
return () => current;
|
|
56
|
+
} else if (Array.isArray(value)) {
|
|
57
|
+
const array = [];
|
|
58
|
+
if (normalizeIncomingArray(array, value, unwrapArray)) {
|
|
59
|
+
createRenderEffect(() => current = insertExpression(parent, array, current, marker, true));
|
|
60
|
+
return () => current;
|
|
61
|
+
}
|
|
62
|
+
if (array.length === 0) {
|
|
63
|
+
const replacement = cleanChildren(parent, current, marker);
|
|
64
|
+
if (multi) return current = replacement;
|
|
65
|
+
} else {
|
|
66
|
+
if (Array.isArray(current)) {
|
|
67
|
+
if (current.length === 0) {
|
|
68
|
+
appendNodes(parent, array, marker);
|
|
69
|
+
} else reconcileArrays(parent, current, array);
|
|
70
|
+
} else if (current == null || current === "") {
|
|
71
|
+
appendNodes(parent, array);
|
|
72
|
+
} else {
|
|
73
|
+
reconcileArrays(parent, multi && current || [getFirstChild(parent)], array);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
current = array;
|
|
77
|
+
} else {
|
|
78
|
+
if (Array.isArray(current)) {
|
|
79
|
+
if (multi) return current = cleanChildren(parent, current, marker, value);
|
|
80
|
+
cleanChildren(parent, current, null, value);
|
|
81
|
+
} else if (current == null || current === "" || !getFirstChild(parent)) {
|
|
82
|
+
insertNode(parent, value);
|
|
83
|
+
} else replaceNode(parent, value, getFirstChild(parent));
|
|
84
|
+
current = value;
|
|
85
|
+
}
|
|
86
|
+
return current;
|
|
87
|
+
}
|
|
88
|
+
function normalizeIncomingArray(normalized, array, unwrap) {
|
|
89
|
+
let dynamic = false;
|
|
90
|
+
for (let i = 0, len = array.length; i < len; i++) {
|
|
91
|
+
let item = array[i],
|
|
92
|
+
t;
|
|
93
|
+
if (item == null || item === true || item === false) ; else if (Array.isArray(item)) {
|
|
94
|
+
dynamic = normalizeIncomingArray(normalized, item) || dynamic;
|
|
95
|
+
} else if ((t = typeof item) === "string" || t === "number") {
|
|
96
|
+
normalized.push(createTextNode(item));
|
|
97
|
+
} else if (t === "function") {
|
|
98
|
+
if (unwrap) {
|
|
99
|
+
while (typeof item === "function") item = item();
|
|
100
|
+
dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item]) || dynamic;
|
|
101
|
+
} else {
|
|
102
|
+
normalized.push(item);
|
|
103
|
+
dynamic = true;
|
|
104
|
+
}
|
|
105
|
+
} else normalized.push(item);
|
|
106
|
+
}
|
|
107
|
+
return dynamic;
|
|
108
|
+
}
|
|
109
|
+
function reconcileArrays(parentNode, a, b) {
|
|
110
|
+
let bLength = b.length,
|
|
111
|
+
aEnd = a.length,
|
|
112
|
+
bEnd = bLength,
|
|
113
|
+
aStart = 0,
|
|
114
|
+
bStart = 0,
|
|
115
|
+
after = getNextSibling(a[aEnd - 1]),
|
|
116
|
+
map = null;
|
|
117
|
+
while (aStart < aEnd || bStart < bEnd) {
|
|
118
|
+
if (a[aStart] === b[bStart]) {
|
|
119
|
+
aStart++;
|
|
120
|
+
bStart++;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
while (a[aEnd - 1] === b[bEnd - 1]) {
|
|
124
|
+
aEnd--;
|
|
125
|
+
bEnd--;
|
|
126
|
+
}
|
|
127
|
+
if (aEnd === aStart) {
|
|
128
|
+
const node = bEnd < bLength ? bStart ? getNextSibling(b[bStart - 1]) : b[bEnd - bStart] : after;
|
|
129
|
+
while (bStart < bEnd) insertNode(parentNode, b[bStart++], node);
|
|
130
|
+
} else if (bEnd === bStart) {
|
|
131
|
+
while (aStart < aEnd) {
|
|
132
|
+
if (!map || !map.has(a[aStart])) removeNode(parentNode, a[aStart]);
|
|
133
|
+
aStart++;
|
|
134
|
+
}
|
|
135
|
+
} else if (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]) {
|
|
136
|
+
const node = getNextSibling(a[--aEnd]);
|
|
137
|
+
insertNode(parentNode, b[bStart++], getNextSibling(a[aStart++]));
|
|
138
|
+
insertNode(parentNode, b[--bEnd], node);
|
|
139
|
+
a[aEnd] = b[bEnd];
|
|
140
|
+
} else {
|
|
141
|
+
if (!map) {
|
|
142
|
+
map = new Map();
|
|
143
|
+
let i = bStart;
|
|
144
|
+
while (i < bEnd) map.set(b[i], i++);
|
|
145
|
+
}
|
|
146
|
+
const index = map.get(a[aStart]);
|
|
147
|
+
if (index != null) {
|
|
148
|
+
if (bStart < index && index < bEnd) {
|
|
149
|
+
let i = aStart,
|
|
150
|
+
sequence = 1,
|
|
151
|
+
t;
|
|
152
|
+
while (++i < aEnd && i < bEnd) {
|
|
153
|
+
if ((t = map.get(a[i])) == null || t !== index + sequence) break;
|
|
154
|
+
sequence++;
|
|
155
|
+
}
|
|
156
|
+
if (sequence > index - bStart) {
|
|
157
|
+
const node = a[aStart];
|
|
158
|
+
while (bStart < index) insertNode(parentNode, b[bStart++], node);
|
|
159
|
+
} else replaceNode(parentNode, b[bStart++], a[aStart++]);
|
|
160
|
+
} else aStart++;
|
|
161
|
+
} else removeNode(parentNode, a[aStart++]);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function cleanChildren(parent, current, marker, replacement) {
|
|
166
|
+
if (marker === undefined) {
|
|
167
|
+
let removed;
|
|
168
|
+
while (removed = getFirstChild(parent)) removeNode(parent, removed);
|
|
169
|
+
replacement && insertNode(parent, replacement);
|
|
170
|
+
return "";
|
|
171
|
+
}
|
|
172
|
+
const node = replacement || createTextNode("");
|
|
173
|
+
if (current.length) {
|
|
174
|
+
let inserted = false;
|
|
175
|
+
for (let i = current.length - 1; i >= 0; i--) {
|
|
176
|
+
const el = current[i];
|
|
177
|
+
if (node !== el) {
|
|
178
|
+
const isParent = getParentNode(el) === parent;
|
|
179
|
+
if (!inserted && !i) isParent ? replaceNode(parent, node, el) : insertNode(parent, node, marker);else isParent && removeNode(parent, el);
|
|
180
|
+
} else inserted = true;
|
|
181
|
+
}
|
|
182
|
+
} else insertNode(parent, node, marker);
|
|
183
|
+
return [node];
|
|
184
|
+
}
|
|
185
|
+
function appendNodes(parent, array, marker) {
|
|
186
|
+
for (let i = 0, len = array.length; i < len; i++) insertNode(parent, array[i], marker);
|
|
187
|
+
}
|
|
188
|
+
function replaceNode(parent, newNode, oldNode) {
|
|
189
|
+
insertNode(parent, newNode, oldNode);
|
|
190
|
+
removeNode(parent, oldNode);
|
|
191
|
+
}
|
|
192
|
+
function spreadExpression(node, props, prevProps = {}, skipChildren) {
|
|
193
|
+
if (!skipChildren && "children" in props) {
|
|
194
|
+
createRenderEffect(() => prevProps.children = insertExpression(node, props.children, prevProps.children));
|
|
195
|
+
}
|
|
196
|
+
createRenderEffect(() => {
|
|
197
|
+
for (const prop in props) {
|
|
198
|
+
if (prop === "children") continue;
|
|
199
|
+
const value = props[prop];
|
|
200
|
+
if (value === prevProps[prop]) continue;
|
|
201
|
+
if (prop === "ref") value(node);else {
|
|
202
|
+
setProperty(node, prop, value, prevProps[prop]);
|
|
203
|
+
prevProps[prop] = value;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
return prevProps;
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
render(code, element) {
|
|
211
|
+
let disposer;
|
|
212
|
+
createRoot(dispose => {
|
|
213
|
+
disposer = dispose;
|
|
214
|
+
insert(element, code());
|
|
215
|
+
});
|
|
216
|
+
return disposer;
|
|
217
|
+
},
|
|
218
|
+
insert,
|
|
219
|
+
spread(node, accessor, skipChildren) {
|
|
220
|
+
if (typeof accessor === "function") {
|
|
221
|
+
createRenderEffect(current => spreadExpression(node, accessor(), current, skipChildren));
|
|
222
|
+
} else spreadExpression(node, accessor, undefined, skipChildren);
|
|
223
|
+
},
|
|
224
|
+
createElement,
|
|
225
|
+
createTextNode,
|
|
226
|
+
insertNode,
|
|
227
|
+
setProp(node, name, value, prev) {
|
|
228
|
+
setProperty(node, name, value, prev);
|
|
229
|
+
return value;
|
|
230
|
+
},
|
|
231
|
+
mergeProps,
|
|
232
|
+
effect: createRenderEffect,
|
|
233
|
+
memo,
|
|
234
|
+
createComponent
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
function mergeProps(...sources) {
|
|
238
|
+
const target = {};
|
|
239
|
+
for (let i = 0; i < sources.length; i++) {
|
|
240
|
+
let source = sources[i];
|
|
241
|
+
if (typeof source === "function") source = source();
|
|
242
|
+
const descriptors = Object.getOwnPropertyDescriptors(source);
|
|
243
|
+
Object.defineProperties(target, descriptors);
|
|
244
|
+
}
|
|
245
|
+
return target;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function createRenderer(options) {
|
|
249
|
+
const renderer = createRenderer$1(options);
|
|
250
|
+
renderer.mergeProps = mergeProps$1;
|
|
251
|
+
return renderer;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export { createRenderer };
|