@viewfly/core 2.0.0 → 2.2.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 +67 -4
- package/dist/_utils/make-error.d.ts +1 -0
- package/dist/base/_api.d.ts +13 -0
- package/dist/base/_utils.d.ts +46 -0
- package/dist/base/component.d.ts +65 -0
- package/dist/base/context.d.ts +42 -0
- package/dist/base/dep.d.ts +9 -0
- package/dist/base/injection-tokens.d.ts +20 -0
- package/dist/base/jsx-element.d.ts +64 -0
- package/dist/base/lifecycle.d.ts +37 -0
- package/dist/base/memo.d.ts +8 -0
- package/dist/base/ref.d.ts +44 -0
- package/dist/base/renderer.d.ts +4 -0
- package/dist/base/root.component.d.ts +9 -0
- package/dist/base/types.d.ts +32 -0
- package/dist/di/_api.d.ts +10 -0
- package/dist/di/forward-ref.d.ts +10 -0
- package/dist/di/injectable.d.ts +20 -0
- package/dist/di/injection-token.d.ts +8 -0
- package/dist/di/injector.d.ts +26 -0
- package/dist/di/metadata.d.ts +43 -0
- package/dist/di/null-injector.d.ts +6 -0
- package/dist/di/provider.d.ts +30 -0
- package/dist/di/reflective-injector.d.ts +30 -0
- package/dist/di/reflective-provider.d.ts +20 -0
- package/dist/di/type.d.ts +7 -0
- package/dist/di/utils/_api.d.ts +3 -0
- package/dist/di/utils/annotations.d.ts +33 -0
- package/dist/di/utils/decorators.d.ts +17 -0
- package/dist/di/utils/stringify.d.ts +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.esm.js +2243 -0
- package/dist/index.js +2322 -0
- package/dist/jsx-runtime/index.d.ts +7 -0
- package/dist/jsx-runtime/index.esm.js +2 -0
- package/dist/jsx-runtime/index.js +26 -0
- package/dist/jsx-runtime.d.ts +7 -0
- package/dist/reactive/_api.d.ts +5 -0
- package/dist/reactive/_help.d.ts +15 -0
- package/dist/reactive/array-handlers.d.ts +30 -0
- package/dist/reactive/computed.d.ts +4 -0
- package/dist/reactive/effect.d.ts +13 -0
- package/dist/reactive/iterable-iterator.d.ts +5 -0
- package/dist/reactive/map-handlers.d.ts +12 -0
- package/dist/reactive/reactive.d.ts +89 -0
- package/dist/reactive/set-handlers.d.ts +11 -0
- package/dist/reactive/shallow-reactive.d.ts +6 -0
- package/dist/reactive/watch.d.ts +1 -0
- package/dist/signals/_api.d.ts +3 -0
- package/dist/signals/derived.d.ts +9 -0
- package/dist/signals/effect.d.ts +22 -0
- package/dist/signals/signal.d.ts +38 -0
- package/dist/viewfly.d.ts +30 -0
- package/package.json +25 -25
- package/bundles/index.d.ts +0 -722
- package/bundles/index.esm.js +0 -2621
- package/bundles/index.js +0 -2695
- package/jsx-runtime/index.d.ts +0 -25
- package/jsx-runtime/index.esm.js +0 -11
- package/jsx-runtime/index.js +0 -14
- package/jsx-runtime/package.json +0 -29
- package/rollup-d.config.ts +0 -14
|
@@ -0,0 +1,2243 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
//#region src/di/forward-ref.ts
|
|
3
|
+
var ForwardRef = class {
|
|
4
|
+
constructor(forwardRefFn) {
|
|
5
|
+
this.forwardRefFn = forwardRefFn;
|
|
6
|
+
}
|
|
7
|
+
getRef() {
|
|
8
|
+
return this.forwardRefFn();
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* 引用后声明的类的工具函数
|
|
13
|
+
* @param fn
|
|
14
|
+
*/
|
|
15
|
+
function forwardRef(fn) {
|
|
16
|
+
return new ForwardRef(fn);
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/di/utils/annotations.ts
|
|
20
|
+
/**
|
|
21
|
+
* 用于保存 class 的元数据
|
|
22
|
+
*/
|
|
23
|
+
var Annotations = class {
|
|
24
|
+
classes = /* @__PURE__ */ new Map();
|
|
25
|
+
props = /* @__PURE__ */ new Map();
|
|
26
|
+
params = /* @__PURE__ */ new Map();
|
|
27
|
+
setClassMetadata(token, params) {
|
|
28
|
+
this.classes.set(token, params);
|
|
29
|
+
}
|
|
30
|
+
getClassMetadata(token) {
|
|
31
|
+
return this.classes.get(token);
|
|
32
|
+
}
|
|
33
|
+
pushParamMetadata(token, params) {
|
|
34
|
+
if (this.params.has(token)) this.params.get(token).push(params);
|
|
35
|
+
else this.params.set(token, [params]);
|
|
36
|
+
}
|
|
37
|
+
getParamMetadata(token) {
|
|
38
|
+
return this.params.get(token);
|
|
39
|
+
}
|
|
40
|
+
getPropMetadataKeys() {
|
|
41
|
+
return Array.from(this.props.keys());
|
|
42
|
+
}
|
|
43
|
+
pushPropMetadata(token, params) {
|
|
44
|
+
if (this.props.has(token)) this.props.get(token).push(params);
|
|
45
|
+
else this.props.set(token, [params]);
|
|
46
|
+
}
|
|
47
|
+
getPropMetadata(token) {
|
|
48
|
+
return this.props.get(token);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/di/utils/decorators.ts
|
|
53
|
+
/**
|
|
54
|
+
* 创建参数装饰器的工厂函数
|
|
55
|
+
*/
|
|
56
|
+
function makeParamDecorator(token, metadata) {
|
|
57
|
+
return function(target, propertyKey, parameterIndex) {
|
|
58
|
+
getAnnotations(target).pushParamMetadata(token, {
|
|
59
|
+
propertyKey,
|
|
60
|
+
parameterIndex,
|
|
61
|
+
metadata
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 创建属性装饰器的工厂函数
|
|
67
|
+
*/
|
|
68
|
+
function makePropertyDecorator(token, injectToken, contextCallback) {
|
|
69
|
+
return function(target, propertyKey) {
|
|
70
|
+
getAnnotations(target.constructor).pushPropMetadata(token, {
|
|
71
|
+
injectToken: injectToken || Reflect.getMetadata("design:type", target, propertyKey),
|
|
72
|
+
propertyKey,
|
|
73
|
+
contextCallback
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 创建类装饰器的工厂函数
|
|
79
|
+
*/
|
|
80
|
+
function makeClassDecorator(token, metadata) {
|
|
81
|
+
return function(target) {
|
|
82
|
+
getAnnotations(target).setClassMetadata(token, {
|
|
83
|
+
paramTypes: Reflect.getMetadata("design:paramtypes", target),
|
|
84
|
+
metadata
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* 获取类注解的工具函数
|
|
90
|
+
*/
|
|
91
|
+
function getAnnotations(target) {
|
|
92
|
+
const key = "__annotations__";
|
|
93
|
+
if (!target.hasOwnProperty(key)) target[key] = new Annotations();
|
|
94
|
+
return target[key];
|
|
95
|
+
}
|
|
96
|
+
//#endregion
|
|
97
|
+
//#region src/di/injectable.ts
|
|
98
|
+
var Scope = class {
|
|
99
|
+
constructor(name) {
|
|
100
|
+
this.name = name;
|
|
101
|
+
}
|
|
102
|
+
toString() {
|
|
103
|
+
return this.name || "[anonymous provide scope]";
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* 可注入类的装饰器
|
|
108
|
+
*/
|
|
109
|
+
var Injectable = function InjectableDecorator(options) {
|
|
110
|
+
if (this instanceof InjectableDecorator) this.provideIn = options?.provideIn || null;
|
|
111
|
+
else return makeClassDecorator(Injectable, new Injectable(options));
|
|
112
|
+
};
|
|
113
|
+
//#endregion
|
|
114
|
+
//#region src/di/injection-token.ts
|
|
115
|
+
/**
|
|
116
|
+
* 生成自定义依赖注入 token 的类
|
|
117
|
+
*/
|
|
118
|
+
var InjectionToken = class {
|
|
119
|
+
constructor(description) {
|
|
120
|
+
this.description = description;
|
|
121
|
+
}
|
|
122
|
+
toString() {
|
|
123
|
+
return this.description || "[anonymous injection token]";
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
//#endregion
|
|
127
|
+
//#region src/di/injector.ts
|
|
128
|
+
/**
|
|
129
|
+
* 查找规则
|
|
130
|
+
*/
|
|
131
|
+
var InjectFlags = /* @__PURE__ */ function(InjectFlags) {
|
|
132
|
+
/** 默认查找规则 */
|
|
133
|
+
InjectFlags["Default"] = "Default";
|
|
134
|
+
/** 锁定当前容器 */
|
|
135
|
+
InjectFlags["Self"] = "Self";
|
|
136
|
+
/** 跳过当前容器 */
|
|
137
|
+
InjectFlags["SkipSelf"] = "SkipSelf";
|
|
138
|
+
/** 可选查找 */
|
|
139
|
+
InjectFlags["Optional"] = "Optional";
|
|
140
|
+
return InjectFlags;
|
|
141
|
+
}({});
|
|
142
|
+
/**
|
|
143
|
+
* DI 容器抽象基类
|
|
144
|
+
*/
|
|
145
|
+
var Injector = class {};
|
|
146
|
+
//#endregion
|
|
147
|
+
//#region src/di/metadata.ts
|
|
148
|
+
/**
|
|
149
|
+
* 构造函数参数装饰器,用于改变注入 token
|
|
150
|
+
*/
|
|
151
|
+
var Inject = function InjectDecorator(token) {
|
|
152
|
+
if (this instanceof Inject) this.token = token;
|
|
153
|
+
else return makeParamDecorator(Inject, new Inject(token));
|
|
154
|
+
};
|
|
155
|
+
var Self = function SelfDecorator() {
|
|
156
|
+
if (!(this instanceof Self)) return makeParamDecorator(Self, new Self());
|
|
157
|
+
};
|
|
158
|
+
var SkipSelf = function SkipSelfDecorator() {
|
|
159
|
+
if (!(this instanceof SkipSelf)) return makeParamDecorator(SkipSelf, new SkipSelf());
|
|
160
|
+
};
|
|
161
|
+
var Optional = function OptionalDecorator() {
|
|
162
|
+
if (!(this instanceof Optional)) return makeParamDecorator(Optional, new Optional());
|
|
163
|
+
};
|
|
164
|
+
var Prop = function PropDecorator(token, notFoundValue, flags) {
|
|
165
|
+
if (!(this instanceof Prop)) return makePropertyDecorator(Prop, token, function(instance, propertyName, token, injector) {
|
|
166
|
+
instance[propertyName] = injector.get(token instanceof ForwardRef ? token.getRef() : token, notFoundValue, flags);
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
//#endregion
|
|
170
|
+
//#region src/di/utils/stringify.ts
|
|
171
|
+
function stringify(token) {
|
|
172
|
+
if (typeof token === "string") return token;
|
|
173
|
+
if (Array.isArray(token)) return "[" + token.map(stringify).join(", ") + "]";
|
|
174
|
+
if (token == null) return "" + token;
|
|
175
|
+
if (token.name) return `${token.name}`;
|
|
176
|
+
if (token.token) return `${token.token}`;
|
|
177
|
+
const res = token.toString();
|
|
178
|
+
if (res == null) return "" + res;
|
|
179
|
+
const newLineIndex = res.indexOf("\n");
|
|
180
|
+
return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
|
|
181
|
+
}
|
|
182
|
+
//#endregion
|
|
183
|
+
//#region src/_utils/make-error.ts
|
|
184
|
+
function makeError(name) {
|
|
185
|
+
return function viewflyError(message) {
|
|
186
|
+
const error = new Error(message);
|
|
187
|
+
error.name = `[ViewflyError: ${name}]`;
|
|
188
|
+
error.stack = error.stack.replace(/\n.*?(?=\n)/, "");
|
|
189
|
+
return error;
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
//#endregion
|
|
193
|
+
//#region src/di/null-injector.ts
|
|
194
|
+
var THROW_IF_NOT_FOUND = { __debug_value__: "THROW_IF_NOT_FOUND" };
|
|
195
|
+
var nullInjectorErrorFn = (token) => {
|
|
196
|
+
return makeError("NullInjector")(`No provide for \`${stringify(token)}\`!`);
|
|
197
|
+
};
|
|
198
|
+
var NullInjector = class {
|
|
199
|
+
parentInjector = null;
|
|
200
|
+
get(token, notFoundValue = THROW_IF_NOT_FOUND, _) {
|
|
201
|
+
if (notFoundValue === THROW_IF_NOT_FOUND) throw nullInjectorErrorFn(token);
|
|
202
|
+
return notFoundValue;
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
//#endregion
|
|
206
|
+
//#region src/di/reflective-provider.ts
|
|
207
|
+
/**
|
|
208
|
+
* 标准化 provide,并返回统一数据结构
|
|
209
|
+
* @param provider
|
|
210
|
+
*/
|
|
211
|
+
function normalizeProvider(provider) {
|
|
212
|
+
if (provider.useValue) return normalizeValueProviderFactory(provider);
|
|
213
|
+
if (provider.useClass) return normalizeClassProviderFactory(provider);
|
|
214
|
+
if (provider.useExisting) return normalizeExistingProviderFactory(provider);
|
|
215
|
+
if (provider.useFactory) return normalizeFactoryProviderFactory(provider);
|
|
216
|
+
if (provider.provide) {
|
|
217
|
+
if (provider.provide instanceof InjectionToken) return normalizeValueProviderFactory(provider);
|
|
218
|
+
return normalizeConstructorProviderFactory(provider);
|
|
219
|
+
}
|
|
220
|
+
return normalizeTypeProviderFactory(provider);
|
|
221
|
+
}
|
|
222
|
+
function normalizeValueProviderFactory(provider) {
|
|
223
|
+
return {
|
|
224
|
+
provide: provider.provide,
|
|
225
|
+
scope: null,
|
|
226
|
+
generateFactory() {
|
|
227
|
+
return function() {
|
|
228
|
+
return provider.useValue;
|
|
229
|
+
};
|
|
230
|
+
},
|
|
231
|
+
deps: []
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
function normalizeClassProviderFactory(provider) {
|
|
235
|
+
let deps;
|
|
236
|
+
let provideIn = null;
|
|
237
|
+
if (provider.deps) deps = normalizeDeps(provider.provide, provider.deps);
|
|
238
|
+
else {
|
|
239
|
+
const resolvedClass = resolveClassParams(provider.useClass);
|
|
240
|
+
provideIn = resolvedClass.scope;
|
|
241
|
+
deps = normalizeDeps(provider.provide, resolvedClass.deps);
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
provide: provider.provide,
|
|
245
|
+
scope: provideIn,
|
|
246
|
+
deps,
|
|
247
|
+
generateFactory(injector, cacheFn) {
|
|
248
|
+
return function(...args) {
|
|
249
|
+
const instance = new provider.useClass(...args);
|
|
250
|
+
cacheFn(provider.provide, instance);
|
|
251
|
+
getAnnotations(provider.useClass).getPropMetadataKeys().forEach((key) => {
|
|
252
|
+
getAnnotations(provider.useClass).getPropMetadata(key).forEach((item) => {
|
|
253
|
+
item.contextCallback(instance, item.propertyKey, item.injectToken, injector);
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
return instance;
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
function normalizeExistingProviderFactory(provider) {
|
|
262
|
+
return {
|
|
263
|
+
provide: provider.provide,
|
|
264
|
+
scope: null,
|
|
265
|
+
generateFactory(injector) {
|
|
266
|
+
return function() {
|
|
267
|
+
return injector.get(provider.useExisting);
|
|
268
|
+
};
|
|
269
|
+
},
|
|
270
|
+
deps: []
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
function normalizeFactoryProviderFactory(provider) {
|
|
274
|
+
return {
|
|
275
|
+
provide: provider.provide,
|
|
276
|
+
scope: null,
|
|
277
|
+
generateFactory() {
|
|
278
|
+
return function(...args) {
|
|
279
|
+
return provider.useFactory(...args);
|
|
280
|
+
};
|
|
281
|
+
},
|
|
282
|
+
deps: normalizeDeps(provider.provide, provider.deps || [])
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
function normalizeConstructorProviderFactory(provider) {
|
|
286
|
+
return normalizeClassProviderFactory({
|
|
287
|
+
...provider,
|
|
288
|
+
useClass: provider.provide
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
function normalizeTypeProviderFactory(provider) {
|
|
292
|
+
return normalizeClassProviderFactory({
|
|
293
|
+
provide: provider,
|
|
294
|
+
useClass: provider
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
function resolveClassParams(construct) {
|
|
298
|
+
const annotations = getAnnotations(construct);
|
|
299
|
+
const metadata = annotations.getClassMetadata(Injectable);
|
|
300
|
+
if (typeof metadata === "undefined") throw new Error(`Class \`${stringify(construct)}\` is not injectable!`);
|
|
301
|
+
const deps = (metadata.paramTypes || []).map((i) => [i]);
|
|
302
|
+
[
|
|
303
|
+
Inject,
|
|
304
|
+
Self,
|
|
305
|
+
SkipSelf,
|
|
306
|
+
Optional
|
|
307
|
+
].forEach((key) => {
|
|
308
|
+
(annotations.getParamMetadata(key) || []).forEach((item) => {
|
|
309
|
+
deps[item.parameterIndex].push(item.metadata);
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
return {
|
|
313
|
+
scope: metadata.metadata.provideIn,
|
|
314
|
+
deps
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
function normalizeDeps(provide, deps) {
|
|
318
|
+
return deps.map((dep, index) => {
|
|
319
|
+
const r = {
|
|
320
|
+
injectKey: null,
|
|
321
|
+
optional: false,
|
|
322
|
+
visibility: null
|
|
323
|
+
};
|
|
324
|
+
if (!Array.isArray(dep)) r.injectKey = dep;
|
|
325
|
+
else for (let i = 0; i < dep.length; i++) {
|
|
326
|
+
const item = dep[i];
|
|
327
|
+
if (item instanceof Inject) r.injectKey = item.token;
|
|
328
|
+
else if (item instanceof Self || item instanceof SkipSelf) r.visibility = item;
|
|
329
|
+
else if (item instanceof Optional) r.optional = true;
|
|
330
|
+
else r.injectKey = item;
|
|
331
|
+
}
|
|
332
|
+
if (typeof r.injectKey === "undefined") throw new Error(`The ${index} th dependent parameter type of \`${stringify(provide)}\` was not obtained, if the dependency is declared later, you can refer to it using \`constructor(@Inject(forwardRef(() => [Type|InjectionToken])) paramName: [Type]) {}\``);
|
|
333
|
+
return r;
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
//#endregion
|
|
337
|
+
//#region src/di/reflective-injector.ts
|
|
338
|
+
var reflectiveInjectorErrorFn = (token) => {
|
|
339
|
+
return makeError("ReflectiveInjector")(`No provide for \`${stringify(token)}\`!`);
|
|
340
|
+
};
|
|
341
|
+
var provideScopeError = (token) => {
|
|
342
|
+
return makeError("ProvideScope")(`Can not found provide scope \`${stringify(token)}\`!`);
|
|
343
|
+
};
|
|
344
|
+
/**
|
|
345
|
+
* 反射注入器
|
|
346
|
+
*/
|
|
347
|
+
var ReflectiveInjector = class {
|
|
348
|
+
normalizedProviders;
|
|
349
|
+
recordValues = /* @__PURE__ */ new Map();
|
|
350
|
+
constructor(parentInjector, staticProviders, scope) {
|
|
351
|
+
this.parentInjector = parentInjector;
|
|
352
|
+
this.scope = scope;
|
|
353
|
+
this.normalizedProviders = staticProviders.map((provide) => {
|
|
354
|
+
return normalizeProvider(provide);
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* 用于获取当前注入器上下文内的实例、对象或数据
|
|
359
|
+
* @param token 访问 token
|
|
360
|
+
* @param notFoundValue 如未查找到的返回值
|
|
361
|
+
* @param flags 查询规则
|
|
362
|
+
*/
|
|
363
|
+
get(token, notFoundValue = THROW_IF_NOT_FOUND, flags) {
|
|
364
|
+
flags = flags || InjectFlags.Default;
|
|
365
|
+
if (flags === InjectFlags.SkipSelf) {
|
|
366
|
+
if (this.parentInjector) return this.parentInjector.get(token, notFoundValue);
|
|
367
|
+
if (notFoundValue !== THROW_IF_NOT_FOUND) return notFoundValue;
|
|
368
|
+
throw reflectiveInjectorErrorFn(token);
|
|
369
|
+
}
|
|
370
|
+
if (this.recordValues.has(token)) return this.recordValues.get(token);
|
|
371
|
+
for (let i = 0; i < this.normalizedProviders.length; i++) {
|
|
372
|
+
const normalizedProvider = this.normalizedProviders[i];
|
|
373
|
+
if (normalizedProvider.provide === token) return this.getValue(token, normalizedProvider);
|
|
374
|
+
}
|
|
375
|
+
if (!(token instanceof InjectionToken)) {
|
|
376
|
+
const scope = getAnnotations(token).getClassMetadata(Injectable)?.metadata.provideIn;
|
|
377
|
+
if (scope) {
|
|
378
|
+
const normalizedProvider = normalizeProvider(token);
|
|
379
|
+
if (this.scope === scope) {
|
|
380
|
+
this.normalizedProviders.push(normalizedProvider);
|
|
381
|
+
return this.getValue(token, normalizedProvider);
|
|
382
|
+
}
|
|
383
|
+
const parentInjector = this.parentInjector;
|
|
384
|
+
if (!parentInjector || parentInjector instanceof NullInjector) {
|
|
385
|
+
if (normalizedProvider.scope === "root") {
|
|
386
|
+
this.normalizedProviders.push(normalizedProvider);
|
|
387
|
+
return this.getValue(token, normalizedProvider);
|
|
388
|
+
}
|
|
389
|
+
if (notFoundValue !== THROW_IF_NOT_FOUND) return notFoundValue;
|
|
390
|
+
throw provideScopeError(normalizedProvider.scope);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
if (flags === InjectFlags.Self) {
|
|
395
|
+
if (notFoundValue === THROW_IF_NOT_FOUND) throw reflectiveInjectorErrorFn(token);
|
|
396
|
+
return notFoundValue;
|
|
397
|
+
}
|
|
398
|
+
if (this.parentInjector) return this.parentInjector.get(token, notFoundValue, flags === InjectFlags.Optional ? InjectFlags.Optional : InjectFlags.Default);
|
|
399
|
+
if (notFoundValue === THROW_IF_NOT_FOUND) throw reflectiveInjectorErrorFn(token);
|
|
400
|
+
return notFoundValue;
|
|
401
|
+
}
|
|
402
|
+
getValue(token, normalizedProvider) {
|
|
403
|
+
const { generateFactory, deps } = normalizedProvider;
|
|
404
|
+
const params = this.resolveDeps(deps);
|
|
405
|
+
let value = this.recordValues.get(token);
|
|
406
|
+
if (value) return value;
|
|
407
|
+
value = generateFactory(this, (token, value) => {
|
|
408
|
+
this.recordValues.set(token, value);
|
|
409
|
+
})(...params);
|
|
410
|
+
this.recordValues.set(token, value);
|
|
411
|
+
return value;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* 解决并获取依赖参数
|
|
415
|
+
* @param deps 依赖规则
|
|
416
|
+
* @private
|
|
417
|
+
*/
|
|
418
|
+
resolveDeps(deps) {
|
|
419
|
+
return deps.map((dep) => {
|
|
420
|
+
let reflectiveValue;
|
|
421
|
+
const tryValue = {};
|
|
422
|
+
const injectToken = dep.injectKey instanceof ForwardRef ? dep.injectKey.getRef() : dep.injectKey;
|
|
423
|
+
if (dep.visibility instanceof Self) reflectiveValue = this.get(injectToken, tryValue, InjectFlags.Self);
|
|
424
|
+
else if (dep.visibility instanceof SkipSelf) if (this.parentInjector) reflectiveValue = this.parentInjector.get(injectToken, tryValue);
|
|
425
|
+
else {
|
|
426
|
+
if (dep.optional) return null;
|
|
427
|
+
throw reflectiveInjectorErrorFn(injectToken);
|
|
428
|
+
}
|
|
429
|
+
else reflectiveValue = this.get(injectToken, tryValue);
|
|
430
|
+
if (reflectiveValue === tryValue) {
|
|
431
|
+
if (dep.optional) return null;
|
|
432
|
+
throw reflectiveInjectorErrorFn(injectToken);
|
|
433
|
+
}
|
|
434
|
+
return reflectiveValue;
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
};
|
|
438
|
+
//#endregion
|
|
439
|
+
//#region src/di/type.ts
|
|
440
|
+
var Type = Function;
|
|
441
|
+
//#endregion
|
|
442
|
+
//#region src/base/lifecycle.ts
|
|
443
|
+
/**
|
|
444
|
+
* 当组件第一次渲染完成时触发
|
|
445
|
+
* @param callback
|
|
446
|
+
* ```tsx
|
|
447
|
+
* function App() {
|
|
448
|
+
* onMount(() => {
|
|
449
|
+
* console.log('App mounted!')
|
|
450
|
+
* })
|
|
451
|
+
* return () => <div>...</div>
|
|
452
|
+
* }
|
|
453
|
+
* ```
|
|
454
|
+
*/
|
|
455
|
+
function onMounted(callback) {
|
|
456
|
+
const component = getSetupContext();
|
|
457
|
+
if (!component.mountCallbacks) component.mountCallbacks = [];
|
|
458
|
+
component.mountCallbacks.push(callback);
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* 当组件视图更新后调用
|
|
462
|
+
* @param callback
|
|
463
|
+
* ```tsx
|
|
464
|
+
* function App() {
|
|
465
|
+
* onUpdated(() => {
|
|
466
|
+
* console.log('App updated!')
|
|
467
|
+
* return () => {
|
|
468
|
+
* console.log('destroy prev update!')
|
|
469
|
+
* }
|
|
470
|
+
* })
|
|
471
|
+
* return () => <div>...</div>
|
|
472
|
+
* }
|
|
473
|
+
* ```
|
|
474
|
+
*/
|
|
475
|
+
function onUpdated(callback) {
|
|
476
|
+
const component = getSetupContext();
|
|
477
|
+
if (!component.updatedCallbacks) component.updatedCallbacks = [];
|
|
478
|
+
component.updatedCallbacks.push(callback);
|
|
479
|
+
return () => {
|
|
480
|
+
const index = component.updatedCallbacks.indexOf(callback);
|
|
481
|
+
if (index > -1) component.updatedCallbacks.splice(index, 1);
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* 当组件销毁时调用回调函数
|
|
486
|
+
* @param callback
|
|
487
|
+
*/
|
|
488
|
+
function onUnmounted(callback) {
|
|
489
|
+
const component = getSetupContext();
|
|
490
|
+
if (!component.unmountedCallbacks) component.unmountedCallbacks = [];
|
|
491
|
+
component.unmountedCallbacks.push(callback);
|
|
492
|
+
}
|
|
493
|
+
//#endregion
|
|
494
|
+
//#region src/base/ref.ts
|
|
495
|
+
var DynamicRef = class {
|
|
496
|
+
unBindMap = /* @__PURE__ */ new Map();
|
|
497
|
+
targetCaches = /* @__PURE__ */ new Set();
|
|
498
|
+
constructor(callback) {
|
|
499
|
+
this.callback = callback;
|
|
500
|
+
}
|
|
501
|
+
bind(value) {
|
|
502
|
+
if (typeof value !== "object" || value === null) return;
|
|
503
|
+
if (this.targetCaches.has(value)) return;
|
|
504
|
+
const unBindFn = this.callback(value);
|
|
505
|
+
if (typeof unBindFn === "function") this.unBindMap.set(value, unBindFn);
|
|
506
|
+
this.targetCaches.add(value);
|
|
507
|
+
}
|
|
508
|
+
unBind(value) {
|
|
509
|
+
this.targetCaches.delete(value);
|
|
510
|
+
const unBindFn = this.unBindMap.get(value);
|
|
511
|
+
this.unBindMap.delete(value);
|
|
512
|
+
if (typeof unBindFn === "function") unBindFn();
|
|
513
|
+
}
|
|
514
|
+
};
|
|
515
|
+
/**
|
|
516
|
+
* 用于节点渲染完成时获取 DOM 节点
|
|
517
|
+
* @param callback 获取 DOM 节点的回调函数
|
|
518
|
+
* @example
|
|
519
|
+
* ```tsx
|
|
520
|
+
* function App() {
|
|
521
|
+
* const ref = createDynamicRef(node => {
|
|
522
|
+
* function fn() {
|
|
523
|
+
* // do something...
|
|
524
|
+
* }
|
|
525
|
+
* node.addEventListener('click', fn)
|
|
526
|
+
* return () => {
|
|
527
|
+
* node.removeEventListener('click', fn)
|
|
528
|
+
* }
|
|
529
|
+
* })
|
|
530
|
+
* return () => {
|
|
531
|
+
* return <div ref={ref}>xxx</div>
|
|
532
|
+
* }
|
|
533
|
+
* }
|
|
534
|
+
* ```
|
|
535
|
+
*/
|
|
536
|
+
function createDynamicRef(callback) {
|
|
537
|
+
return new DynamicRef(callback);
|
|
538
|
+
}
|
|
539
|
+
var StaticRef = class extends DynamicRef {
|
|
540
|
+
get current() {
|
|
541
|
+
return this._current;
|
|
542
|
+
}
|
|
543
|
+
_current = null;
|
|
544
|
+
constructor() {
|
|
545
|
+
super((v) => {
|
|
546
|
+
this._current = v;
|
|
547
|
+
return () => {
|
|
548
|
+
this._current = null;
|
|
549
|
+
};
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
function createRef() {
|
|
554
|
+
return new StaticRef();
|
|
555
|
+
}
|
|
556
|
+
//#endregion
|
|
557
|
+
//#region src/reactive/_help.ts
|
|
558
|
+
var toStr = Object.prototype.toString;
|
|
559
|
+
function getStringType(v) {
|
|
560
|
+
return toStr.call(v);
|
|
561
|
+
}
|
|
562
|
+
function isArray(v) {
|
|
563
|
+
return Array.isArray(v);
|
|
564
|
+
}
|
|
565
|
+
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
566
|
+
function hasOwn(target, key) {
|
|
567
|
+
return hasOwnProperty.call(target, key);
|
|
568
|
+
}
|
|
569
|
+
//#endregion
|
|
570
|
+
//#region src/base/dep.ts
|
|
571
|
+
var Dep = class {
|
|
572
|
+
destroyCallbacks = [];
|
|
573
|
+
constructor(effect) {
|
|
574
|
+
this.effect = effect;
|
|
575
|
+
}
|
|
576
|
+
destroy() {
|
|
577
|
+
this.destroyCallbacks.forEach((callback) => callback());
|
|
578
|
+
this.destroyCallbacks = [];
|
|
579
|
+
}
|
|
580
|
+
};
|
|
581
|
+
var deps = [];
|
|
582
|
+
function getDepContext() {
|
|
583
|
+
return deps.at(-1);
|
|
584
|
+
}
|
|
585
|
+
function pushDepContext(dep) {
|
|
586
|
+
deps.push(dep);
|
|
587
|
+
}
|
|
588
|
+
function popDepContext() {
|
|
589
|
+
deps.pop();
|
|
590
|
+
}
|
|
591
|
+
//#endregion
|
|
592
|
+
//#region src/reactive/effect.ts
|
|
593
|
+
var subscribers = /* @__PURE__ */ new WeakMap();
|
|
594
|
+
function getSubscriber(target) {
|
|
595
|
+
let subscriber = subscribers.get(target);
|
|
596
|
+
if (!subscriber) {
|
|
597
|
+
subscriber = /* @__PURE__ */ new Map();
|
|
598
|
+
subscribers.set(target, subscriber);
|
|
599
|
+
}
|
|
600
|
+
return subscriber;
|
|
601
|
+
}
|
|
602
|
+
var TrackOpTypes = /* @__PURE__ */ function(TrackOpTypes) {
|
|
603
|
+
TrackOpTypes["Get"] = "Get";
|
|
604
|
+
TrackOpTypes["Has"] = "Has";
|
|
605
|
+
TrackOpTypes["Iterate"] = "Iterate";
|
|
606
|
+
return TrackOpTypes;
|
|
607
|
+
}({});
|
|
608
|
+
var TriggerOpTypes = /* @__PURE__ */ function(TriggerOpTypes) {
|
|
609
|
+
TriggerOpTypes["Set"] = "Set";
|
|
610
|
+
TriggerOpTypes["Add"] = "Add";
|
|
611
|
+
TriggerOpTypes["Delete"] = "Delete";
|
|
612
|
+
TriggerOpTypes["Clear"] = "Clear";
|
|
613
|
+
return TriggerOpTypes;
|
|
614
|
+
}({});
|
|
615
|
+
var unKnownKey = Symbol("unKnownKey");
|
|
616
|
+
function track(target, type, key = unKnownKey) {
|
|
617
|
+
const dep = getDepContext();
|
|
618
|
+
if (dep) {
|
|
619
|
+
const subscriber = getSubscriber(target);
|
|
620
|
+
let record = subscriber.get(type);
|
|
621
|
+
if (!record) {
|
|
622
|
+
record = /* @__PURE__ */ new Map();
|
|
623
|
+
subscriber.set(type, record);
|
|
624
|
+
}
|
|
625
|
+
let effects = record.get(key);
|
|
626
|
+
if (!effects) {
|
|
627
|
+
effects = new Set([dep]);
|
|
628
|
+
record.set(key, effects);
|
|
629
|
+
dep.destroyCallbacks.push(() => {
|
|
630
|
+
effects.delete(dep);
|
|
631
|
+
});
|
|
632
|
+
} else if (!effects.has(dep)) {
|
|
633
|
+
dep.destroyCallbacks.push(() => {
|
|
634
|
+
effects.delete(dep);
|
|
635
|
+
});
|
|
636
|
+
effects.add(dep);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
function runEffect(key, record) {
|
|
641
|
+
if (!record) return;
|
|
642
|
+
const effects = record.get(key);
|
|
643
|
+
if (effects) [...effects].forEach((i) => i.effect());
|
|
644
|
+
}
|
|
645
|
+
function trigger(target, type, key = unKnownKey) {
|
|
646
|
+
const subscriber = getSubscriber(target);
|
|
647
|
+
if (subscriber) switch (type) {
|
|
648
|
+
case TriggerOpTypes.Set:
|
|
649
|
+
if (isArray(target)) runEffect(unKnownKey, subscriber.get(TrackOpTypes.Iterate));
|
|
650
|
+
runEffect(key, subscriber.get(TrackOpTypes.Get));
|
|
651
|
+
runEffect(key, subscriber.get(TrackOpTypes.Has));
|
|
652
|
+
break;
|
|
653
|
+
case TriggerOpTypes.Add:
|
|
654
|
+
case TriggerOpTypes.Clear:
|
|
655
|
+
case TriggerOpTypes.Delete:
|
|
656
|
+
runEffect(unKnownKey, subscriber.get(TrackOpTypes.Iterate));
|
|
657
|
+
runEffect(key, subscriber.get(TrackOpTypes.Has));
|
|
658
|
+
runEffect(key, subscriber.get(TrackOpTypes.Get));
|
|
659
|
+
break;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
//#endregion
|
|
663
|
+
//#region src/reactive/iterable-iterator.ts
|
|
664
|
+
function createIterableIterator(wrapper) {
|
|
665
|
+
return {
|
|
666
|
+
*entries() {
|
|
667
|
+
const target = toRaw(this);
|
|
668
|
+
track(target, TrackOpTypes.Iterate);
|
|
669
|
+
for (const [key, value] of target.entries()) yield [wrapper(key), wrapper(value)];
|
|
670
|
+
},
|
|
671
|
+
*keys() {
|
|
672
|
+
const target = toRaw(this);
|
|
673
|
+
track(target, TrackOpTypes.Iterate);
|
|
674
|
+
for (const item of target.keys()) yield wrapper(item);
|
|
675
|
+
},
|
|
676
|
+
*values() {
|
|
677
|
+
const target = toRaw(this);
|
|
678
|
+
track(target, TrackOpTypes.Iterate);
|
|
679
|
+
for (const item of target.values()) yield wrapper(item);
|
|
680
|
+
}
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
//#endregion
|
|
684
|
+
//#region src/reactive/array-handlers.ts
|
|
685
|
+
function applyPredicateMethod(self, methodName, predicate, wrapper, thisArg) {
|
|
686
|
+
const target = toRaw(self);
|
|
687
|
+
track(target, TrackOpTypes.Iterate);
|
|
688
|
+
return target[methodName]((value, index, array) => {
|
|
689
|
+
return predicate.call(target, wrapper(value), index, array);
|
|
690
|
+
}, thisArg);
|
|
691
|
+
}
|
|
692
|
+
function applySearchMethod(self, methodName, args) {
|
|
693
|
+
const target = toRaw(self);
|
|
694
|
+
track(target, TrackOpTypes.Iterate);
|
|
695
|
+
return target[methodName](...args.map(toRaw));
|
|
696
|
+
}
|
|
697
|
+
function createArrayHandlers(wrapper) {
|
|
698
|
+
return {
|
|
699
|
+
concat(...items) {
|
|
700
|
+
const target = toRaw(this);
|
|
701
|
+
trigger(target, TriggerOpTypes.Add);
|
|
702
|
+
return target.concat(...items);
|
|
703
|
+
},
|
|
704
|
+
every(predicate, thisArg) {
|
|
705
|
+
return applyPredicateMethod(this, "every", predicate, wrapper, thisArg);
|
|
706
|
+
},
|
|
707
|
+
filter(predicate, thisArg) {
|
|
708
|
+
return applyPredicateMethod(this, "filter", predicate, wrapper, thisArg);
|
|
709
|
+
},
|
|
710
|
+
find(predicate, thisArg) {
|
|
711
|
+
return applyPredicateMethod(this, "find", predicate, wrapper, thisArg);
|
|
712
|
+
},
|
|
713
|
+
findIndex(predicate, thisArg) {
|
|
714
|
+
return applyPredicateMethod(this, "findIndex", predicate, wrapper, thisArg);
|
|
715
|
+
},
|
|
716
|
+
findLast(predicate, thisArg) {
|
|
717
|
+
return applyPredicateMethod(this, "findLast", predicate, wrapper, thisArg);
|
|
718
|
+
},
|
|
719
|
+
findLastIndex(predicate, thisArg) {
|
|
720
|
+
return applyPredicateMethod(this, "findLastIndex", predicate, wrapper, thisArg);
|
|
721
|
+
},
|
|
722
|
+
forEach(callbackfn, thisArg) {
|
|
723
|
+
return applyPredicateMethod(this, "forEach", callbackfn, wrapper, thisArg);
|
|
724
|
+
},
|
|
725
|
+
includes(...args) {
|
|
726
|
+
return applySearchMethod(this, "includes", args);
|
|
727
|
+
},
|
|
728
|
+
indexOf(...args) {
|
|
729
|
+
return applySearchMethod(this, "indexOf", args);
|
|
730
|
+
},
|
|
731
|
+
join(separator) {
|
|
732
|
+
const target = toRaw(this);
|
|
733
|
+
track(target, TrackOpTypes.Iterate);
|
|
734
|
+
return target.join(separator);
|
|
735
|
+
},
|
|
736
|
+
lastIndexOf(...args) {
|
|
737
|
+
return applySearchMethod(this, "lastIndexOf", args);
|
|
738
|
+
},
|
|
739
|
+
map(callbackFn, thisArg) {
|
|
740
|
+
return applyPredicateMethod(this, "map", callbackFn, wrapper, thisArg);
|
|
741
|
+
},
|
|
742
|
+
pop() {
|
|
743
|
+
const target = toRaw(this);
|
|
744
|
+
trigger(target, TriggerOpTypes.Delete);
|
|
745
|
+
return target.pop();
|
|
746
|
+
},
|
|
747
|
+
push(...items) {
|
|
748
|
+
const target = toRaw(this);
|
|
749
|
+
trigger(target, TriggerOpTypes.Add);
|
|
750
|
+
return target.push(...items);
|
|
751
|
+
},
|
|
752
|
+
reduce(callbackFn, ...args) {
|
|
753
|
+
const target = toRaw(this);
|
|
754
|
+
track(target, TrackOpTypes.Iterate);
|
|
755
|
+
return target.reduce((p, c, i, a) => {
|
|
756
|
+
if (args.length > 0) return callbackFn(p, wrapper(c), i, a);
|
|
757
|
+
return callbackFn(wrapper(p), wrapper(c), i, a);
|
|
758
|
+
}, ...args);
|
|
759
|
+
},
|
|
760
|
+
reduceRight(callbackFn, ...args) {
|
|
761
|
+
const target = toRaw(this);
|
|
762
|
+
track(target, TrackOpTypes.Iterate);
|
|
763
|
+
return target.reduceRight((p, c, i, a) => {
|
|
764
|
+
if (args.length > 0) return callbackFn(p, wrapper(c), i, a);
|
|
765
|
+
return callbackFn(wrapper(p), wrapper(c), i, a);
|
|
766
|
+
}, ...args);
|
|
767
|
+
},
|
|
768
|
+
shift() {
|
|
769
|
+
const target = toRaw(this);
|
|
770
|
+
trigger(target, TriggerOpTypes.Delete);
|
|
771
|
+
return target.shift();
|
|
772
|
+
},
|
|
773
|
+
some(predicate, thisArg) {
|
|
774
|
+
return applyPredicateMethod(this, "some", predicate, wrapper, thisArg);
|
|
775
|
+
},
|
|
776
|
+
splice(start, deleteCount) {
|
|
777
|
+
const target = toRaw(this);
|
|
778
|
+
trigger(target, TriggerOpTypes.Set);
|
|
779
|
+
trigger(target, TriggerOpTypes.Add);
|
|
780
|
+
trigger(target, TriggerOpTypes.Delete);
|
|
781
|
+
return target.splice(start, deleteCount).map((i) => wrapper(i));
|
|
782
|
+
},
|
|
783
|
+
toReversed() {
|
|
784
|
+
const target = toRaw(this);
|
|
785
|
+
track(target, TrackOpTypes.Iterate);
|
|
786
|
+
return target.toReversed();
|
|
787
|
+
},
|
|
788
|
+
toSorted(compareFn) {
|
|
789
|
+
const target = toRaw(this);
|
|
790
|
+
track(target, TrackOpTypes.Iterate);
|
|
791
|
+
return target.toSorted(compareFn);
|
|
792
|
+
},
|
|
793
|
+
toSpliced(start, deleteCount, ...items) {
|
|
794
|
+
const target = toRaw(this);
|
|
795
|
+
track(target, TrackOpTypes.Iterate);
|
|
796
|
+
return target.toSpliced(start, deleteCount, ...items);
|
|
797
|
+
},
|
|
798
|
+
unshift(...items) {
|
|
799
|
+
const target = toRaw(this);
|
|
800
|
+
trigger(target, TriggerOpTypes.Add);
|
|
801
|
+
return target.unshift(...items);
|
|
802
|
+
},
|
|
803
|
+
[Symbol.iterator]() {
|
|
804
|
+
return this.values();
|
|
805
|
+
},
|
|
806
|
+
...createIterableIterator(wrapper)
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
//#endregion
|
|
810
|
+
//#region src/reactive/map-handlers.ts
|
|
811
|
+
function createMapHandlers(wrapper) {
|
|
812
|
+
return {
|
|
813
|
+
get(key) {
|
|
814
|
+
const target = toRaw(this);
|
|
815
|
+
track(target, TrackOpTypes.Get, key);
|
|
816
|
+
return wrapper(target.get(key));
|
|
817
|
+
},
|
|
818
|
+
set(key, value) {
|
|
819
|
+
const target = toRaw(this);
|
|
820
|
+
key = toRaw(key);
|
|
821
|
+
value = toRaw(value);
|
|
822
|
+
const has = target.has(key);
|
|
823
|
+
const r = target.set(key, value);
|
|
824
|
+
trigger(target, has ? TriggerOpTypes.Set : TriggerOpTypes.Add, key);
|
|
825
|
+
return r;
|
|
826
|
+
},
|
|
827
|
+
has(key) {
|
|
828
|
+
const target = toRaw(this);
|
|
829
|
+
key = toRaw(key);
|
|
830
|
+
track(target, TrackOpTypes.Has, key);
|
|
831
|
+
return target.has(key);
|
|
832
|
+
},
|
|
833
|
+
delete(key) {
|
|
834
|
+
const target = toRaw(this);
|
|
835
|
+
key = toRaw(key);
|
|
836
|
+
const r = target.delete(key);
|
|
837
|
+
trigger(target, TriggerOpTypes.Delete, key);
|
|
838
|
+
return r;
|
|
839
|
+
},
|
|
840
|
+
forEach(callbackFn, thisArg) {
|
|
841
|
+
const target = toRaw(this);
|
|
842
|
+
track(target, TrackOpTypes.Iterate, void 0);
|
|
843
|
+
target.forEach((v, k, m) => {
|
|
844
|
+
callbackFn.call(this, wrapper(v), wrapper(k), m);
|
|
845
|
+
}, thisArg);
|
|
846
|
+
},
|
|
847
|
+
clear() {
|
|
848
|
+
const target = toRaw(this);
|
|
849
|
+
target.clear();
|
|
850
|
+
trigger(target, TriggerOpTypes.Clear, void 0);
|
|
851
|
+
},
|
|
852
|
+
[Symbol.iterator]() {
|
|
853
|
+
return this.entries();
|
|
854
|
+
},
|
|
855
|
+
...createIterableIterator(wrapper)
|
|
856
|
+
};
|
|
857
|
+
}
|
|
858
|
+
//#endregion
|
|
859
|
+
//#region src/reactive/set-handlers.ts
|
|
860
|
+
function createSetHandlers(wrapper) {
|
|
861
|
+
return {
|
|
862
|
+
add(value) {
|
|
863
|
+
const target = toRaw(this);
|
|
864
|
+
value = toRaw(value);
|
|
865
|
+
if (!target.has(value)) {
|
|
866
|
+
target.add(value);
|
|
867
|
+
trigger(target, TriggerOpTypes.Add, void 0);
|
|
868
|
+
}
|
|
869
|
+
return this;
|
|
870
|
+
},
|
|
871
|
+
delete(value) {
|
|
872
|
+
const target = toRaw(this);
|
|
873
|
+
value = toRaw(value);
|
|
874
|
+
const has = target.has(value);
|
|
875
|
+
const b = target.delete(value);
|
|
876
|
+
if (!has) trigger(target, TriggerOpTypes.Delete, void 0);
|
|
877
|
+
return b;
|
|
878
|
+
},
|
|
879
|
+
has(key) {
|
|
880
|
+
const target = toRaw(this);
|
|
881
|
+
key = toRaw(key);
|
|
882
|
+
track(target, TrackOpTypes.Has, key);
|
|
883
|
+
return target.has(key);
|
|
884
|
+
},
|
|
885
|
+
forEach(callbackFn, thisArg) {
|
|
886
|
+
const target = toRaw(this);
|
|
887
|
+
track(target, TrackOpTypes.Iterate, void 0);
|
|
888
|
+
target.forEach((v, k, m) => {
|
|
889
|
+
callbackFn.call(this, wrapper(v), wrapper(k), m);
|
|
890
|
+
}, thisArg);
|
|
891
|
+
},
|
|
892
|
+
clear() {
|
|
893
|
+
const target = toRaw(this);
|
|
894
|
+
if (target.size !== 0) {
|
|
895
|
+
target.clear();
|
|
896
|
+
trigger(target, TriggerOpTypes.Clear, void 0);
|
|
897
|
+
}
|
|
898
|
+
},
|
|
899
|
+
[Symbol.iterator]() {
|
|
900
|
+
return this.values();
|
|
901
|
+
},
|
|
902
|
+
...createIterableIterator(wrapper)
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
//#endregion
|
|
906
|
+
//#region src/reactive/reactive.ts
|
|
907
|
+
var reactiveErrorFn = makeError("reactive");
|
|
908
|
+
var rawToProxyCache = /* @__PURE__ */ new WeakMap();
|
|
909
|
+
var proxyToRawCache = /* @__PURE__ */ new WeakMap();
|
|
910
|
+
function toRaw(value) {
|
|
911
|
+
if (proxyToRawCache.has(value)) return proxyToRawCache.get(value);
|
|
912
|
+
return value;
|
|
913
|
+
}
|
|
914
|
+
function isReactive(value) {
|
|
915
|
+
return proxyToRawCache.has(value);
|
|
916
|
+
}
|
|
917
|
+
var fromInternalWrite = false;
|
|
918
|
+
function internalWrite(fn) {
|
|
919
|
+
fromInternalWrite = true;
|
|
920
|
+
fn();
|
|
921
|
+
fromInternalWrite = false;
|
|
922
|
+
}
|
|
923
|
+
var ObjectReactiveHandler = class {
|
|
924
|
+
isShallow;
|
|
925
|
+
isReadonly;
|
|
926
|
+
constructor(config) {
|
|
927
|
+
this.isReadonly = config.readonly;
|
|
928
|
+
this.isShallow = config.shallow;
|
|
929
|
+
}
|
|
930
|
+
set(target, p, newValue, receiver) {
|
|
931
|
+
if (this.isReadonly && !fromInternalWrite) throw reactiveErrorFn("Object is readonly!");
|
|
932
|
+
const rawValue = toRaw(newValue);
|
|
933
|
+
const oldValue = target[p];
|
|
934
|
+
const v = this.isShallow ? newValue : rawValue;
|
|
935
|
+
if (oldValue === rawValue) return Reflect.set(target, p, v, receiver);
|
|
936
|
+
const b = Reflect.set(target, p, v, receiver);
|
|
937
|
+
fromInternalWrite = false;
|
|
938
|
+
if (hasOwn(target, p)) trigger(target, TriggerOpTypes.Set, p);
|
|
939
|
+
else trigger(target, TriggerOpTypes.Add, p);
|
|
940
|
+
return b;
|
|
941
|
+
}
|
|
942
|
+
get(target, p, receiver) {
|
|
943
|
+
track(target, TrackOpTypes.Get, p);
|
|
944
|
+
const value = Reflect.get(target, p, receiver);
|
|
945
|
+
if (this.isShallow) return value;
|
|
946
|
+
return reactive(value);
|
|
947
|
+
}
|
|
948
|
+
deleteProperty(target, p) {
|
|
949
|
+
const b = Reflect.deleteProperty(target, p);
|
|
950
|
+
trigger(target, TriggerOpTypes.Delete, p);
|
|
951
|
+
return b;
|
|
952
|
+
}
|
|
953
|
+
ownKeys(target) {
|
|
954
|
+
track(target, TrackOpTypes.Iterate);
|
|
955
|
+
return Reflect.ownKeys(target);
|
|
956
|
+
}
|
|
957
|
+
};
|
|
958
|
+
function noReactive(v) {
|
|
959
|
+
return v;
|
|
960
|
+
}
|
|
961
|
+
var ArrayReactiveHandler = class extends ObjectReactiveHandler {
|
|
962
|
+
interceptors = createArrayHandlers(this.isShallow ? noReactive : reactive);
|
|
963
|
+
constructor(config) {
|
|
964
|
+
super(config);
|
|
965
|
+
}
|
|
966
|
+
get(target, p, receiver) {
|
|
967
|
+
if (Reflect.has(this.interceptors, p) && p in target) return this.interceptors[p];
|
|
968
|
+
return super.get(target, p, receiver);
|
|
969
|
+
}
|
|
970
|
+
};
|
|
971
|
+
var MapReactiveHandler = class extends ObjectReactiveHandler {
|
|
972
|
+
interceptors = createMapHandlers(this.isShallow ? noReactive : reactive);
|
|
973
|
+
constructor(config) {
|
|
974
|
+
super(config);
|
|
975
|
+
}
|
|
976
|
+
get(target, p, receiver) {
|
|
977
|
+
if (Reflect.has(this.interceptors, p) && p in target) return this.interceptors[p];
|
|
978
|
+
if (p === "size") {
|
|
979
|
+
track(target, TrackOpTypes.Iterate, p);
|
|
980
|
+
return Reflect.get(target, p);
|
|
981
|
+
}
|
|
982
|
+
return super.get(target, p, receiver);
|
|
983
|
+
}
|
|
984
|
+
};
|
|
985
|
+
var SetReactiveHandler = class extends ObjectReactiveHandler {
|
|
986
|
+
interceptors = createSetHandlers(this.isShallow ? noReactive : reactive);
|
|
987
|
+
constructor(config) {
|
|
988
|
+
super(config);
|
|
989
|
+
}
|
|
990
|
+
get(target, p, receiver) {
|
|
991
|
+
if (Reflect.has(this.interceptors, p) && p in target) return this.interceptors[p];
|
|
992
|
+
if (p === "size") {
|
|
993
|
+
track(target, TrackOpTypes.Iterate, p);
|
|
994
|
+
return Reflect.get(target, p);
|
|
995
|
+
}
|
|
996
|
+
return super.get(target, p, receiver);
|
|
997
|
+
}
|
|
998
|
+
};
|
|
999
|
+
var defaultObjectReactiveHandler = new ObjectReactiveHandler({
|
|
1000
|
+
readonly: false,
|
|
1001
|
+
shallow: false
|
|
1002
|
+
});
|
|
1003
|
+
var defaultArrayReactiveHandler = new ArrayReactiveHandler({
|
|
1004
|
+
readonly: false,
|
|
1005
|
+
shallow: false
|
|
1006
|
+
});
|
|
1007
|
+
var defaultMapReactiveHandler = new MapReactiveHandler({
|
|
1008
|
+
readonly: false,
|
|
1009
|
+
shallow: false
|
|
1010
|
+
});
|
|
1011
|
+
var defaultSetReactiveHandler = new SetReactiveHandler({
|
|
1012
|
+
readonly: false,
|
|
1013
|
+
shallow: false
|
|
1014
|
+
});
|
|
1015
|
+
var readonlyProxyHandler = new ObjectReactiveHandler({
|
|
1016
|
+
shallow: true,
|
|
1017
|
+
readonly: true
|
|
1018
|
+
});
|
|
1019
|
+
function reactive(raw) {
|
|
1020
|
+
if (isReactive(raw)) return raw;
|
|
1021
|
+
let proxy = rawToProxyCache.get(raw);
|
|
1022
|
+
if (proxy) return proxy;
|
|
1023
|
+
switch (getStringType(raw)) {
|
|
1024
|
+
case "[object Object]":
|
|
1025
|
+
proxy = new Proxy(raw, defaultObjectReactiveHandler);
|
|
1026
|
+
break;
|
|
1027
|
+
case "[object Array]":
|
|
1028
|
+
proxy = new Proxy(raw, defaultArrayReactiveHandler);
|
|
1029
|
+
break;
|
|
1030
|
+
case "[object Set]":
|
|
1031
|
+
case "[object WeakSet]":
|
|
1032
|
+
proxy = new Proxy(raw, defaultSetReactiveHandler);
|
|
1033
|
+
break;
|
|
1034
|
+
case "[object Map]":
|
|
1035
|
+
case "[object WeakMap]":
|
|
1036
|
+
proxy = new Proxy(raw, defaultMapReactiveHandler);
|
|
1037
|
+
break;
|
|
1038
|
+
default: return raw;
|
|
1039
|
+
}
|
|
1040
|
+
rawToProxyCache.set(raw, proxy);
|
|
1041
|
+
proxyToRawCache.set(proxy, raw);
|
|
1042
|
+
return proxy;
|
|
1043
|
+
}
|
|
1044
|
+
//#endregion
|
|
1045
|
+
//#region src/base/_utils.ts
|
|
1046
|
+
function hasChange(newProps, oldProps) {
|
|
1047
|
+
const newKeys = Object.keys(oldProps);
|
|
1048
|
+
const oldKeys = Object.keys(newProps);
|
|
1049
|
+
if (oldKeys.length !== newKeys.length) return true;
|
|
1050
|
+
const len = oldKeys.length;
|
|
1051
|
+
for (let i = 0; i < len; i++) {
|
|
1052
|
+
const key = newKeys[i];
|
|
1053
|
+
if (newProps[key] !== oldProps[key]) return true;
|
|
1054
|
+
}
|
|
1055
|
+
return false;
|
|
1056
|
+
}
|
|
1057
|
+
function comparePropsWithCallbacks(oldProps, newProps, onDeleted, onAdded, onUpdated) {
|
|
1058
|
+
for (const key in oldProps) if (!(key in newProps)) onDeleted(key, oldProps[key]);
|
|
1059
|
+
for (const key in newProps) if (!(key in oldProps)) onAdded(key, newProps[key]);
|
|
1060
|
+
else if (oldProps[key] !== newProps[key]) onUpdated(key, newProps[key], oldProps[key]);
|
|
1061
|
+
}
|
|
1062
|
+
function classToString(config) {
|
|
1063
|
+
if (typeof config === "string") return config;
|
|
1064
|
+
if (!config) return "";
|
|
1065
|
+
if (Array.isArray(config)) {
|
|
1066
|
+
const classes = [];
|
|
1067
|
+
for (const i of config) {
|
|
1068
|
+
const v = classToString(i);
|
|
1069
|
+
if (v) classes.push(v);
|
|
1070
|
+
}
|
|
1071
|
+
return classes.join(" ");
|
|
1072
|
+
}
|
|
1073
|
+
if (typeof config === "object") {
|
|
1074
|
+
if (config.toString !== Object.prototype.toString && !config.toString.toString().includes("[native code]")) return config.toString();
|
|
1075
|
+
const classes = [];
|
|
1076
|
+
for (const key in config) if ({}.hasOwnProperty.call(config, key) && config[key]) classes.push(key);
|
|
1077
|
+
return classes.join(" ");
|
|
1078
|
+
}
|
|
1079
|
+
return "";
|
|
1080
|
+
}
|
|
1081
|
+
function styleToObject(style) {
|
|
1082
|
+
if (typeof style !== "string") return style || {};
|
|
1083
|
+
const obj = {};
|
|
1084
|
+
style.split(";").map((s) => s.split(":")).forEach((v) => {
|
|
1085
|
+
if (!v[0] || !v[1]) return;
|
|
1086
|
+
obj[v[0].trim()] = v[1].trim();
|
|
1087
|
+
});
|
|
1088
|
+
return obj;
|
|
1089
|
+
}
|
|
1090
|
+
var TextAtomType = Symbol("Text");
|
|
1091
|
+
var ElementAtomType = Symbol("Element");
|
|
1092
|
+
var ComponentAtomType = Symbol("Component");
|
|
1093
|
+
//#endregion
|
|
1094
|
+
//#region src/base/component.ts
|
|
1095
|
+
var componentSetupStack = [];
|
|
1096
|
+
var componentErrorFn = makeError("component");
|
|
1097
|
+
function getSetupContext(need = true) {
|
|
1098
|
+
const current = componentSetupStack[componentSetupStack.length - 1];
|
|
1099
|
+
if (!current && need) throw componentErrorFn("cannot be called outside the component!");
|
|
1100
|
+
return current;
|
|
1101
|
+
}
|
|
1102
|
+
function toRefs(ref) {
|
|
1103
|
+
return (Array.isArray(ref) ? ref : [ref]).filter((i) => {
|
|
1104
|
+
return i instanceof DynamicRef;
|
|
1105
|
+
});
|
|
1106
|
+
}
|
|
1107
|
+
function createReadonlyProxy(value) {
|
|
1108
|
+
return new Proxy(value, readonlyProxyHandler);
|
|
1109
|
+
}
|
|
1110
|
+
/**
|
|
1111
|
+
* Viewfly 组件管理类,用于管理组件的生命周期,上下文等
|
|
1112
|
+
*/
|
|
1113
|
+
var Component = class {
|
|
1114
|
+
get dirty() {
|
|
1115
|
+
return this._dirty;
|
|
1116
|
+
}
|
|
1117
|
+
get changed() {
|
|
1118
|
+
return this._changed;
|
|
1119
|
+
}
|
|
1120
|
+
constructor(parentComponent, type, props, key) {
|
|
1121
|
+
this.parentComponent = parentComponent;
|
|
1122
|
+
this.type = type;
|
|
1123
|
+
this.props = props;
|
|
1124
|
+
this.key = key;
|
|
1125
|
+
this.instance = null;
|
|
1126
|
+
this.changedSubComponents = /* @__PURE__ */ new Set();
|
|
1127
|
+
this.viewMetadata = null;
|
|
1128
|
+
this.unmountedCallbacks = null;
|
|
1129
|
+
this.mountCallbacks = null;
|
|
1130
|
+
this.updatedCallbacks = null;
|
|
1131
|
+
this.updatedDestroyCallbacks = null;
|
|
1132
|
+
this._dirty = true;
|
|
1133
|
+
this._changed = false;
|
|
1134
|
+
this.isFirstRendering = true;
|
|
1135
|
+
this.refs = null;
|
|
1136
|
+
this.rawProps = props;
|
|
1137
|
+
this.props = createReadonlyProxy({ ...props });
|
|
1138
|
+
this.listener = new Dep(() => {
|
|
1139
|
+
this.markAsDirtied();
|
|
1140
|
+
});
|
|
1141
|
+
}
|
|
1142
|
+
markAsDirtied() {
|
|
1143
|
+
this._dirty = true;
|
|
1144
|
+
this.markAsChanged();
|
|
1145
|
+
}
|
|
1146
|
+
markAsChanged(changedComponent) {
|
|
1147
|
+
if (changedComponent) this.changedSubComponents.add(changedComponent);
|
|
1148
|
+
if (this._changed) return;
|
|
1149
|
+
this._changed = true;
|
|
1150
|
+
if (this.parentComponent) this.parentComponent.markAsChanged(this);
|
|
1151
|
+
}
|
|
1152
|
+
render(update) {
|
|
1153
|
+
componentSetupStack.push(this);
|
|
1154
|
+
const render = this.type(this.props);
|
|
1155
|
+
const isRenderFn = typeof render === "function";
|
|
1156
|
+
this.instance = isRenderFn ? { $render: render } : render;
|
|
1157
|
+
const refs = toRefs(this.props.ref);
|
|
1158
|
+
if (refs.length) {
|
|
1159
|
+
this.refs = refs;
|
|
1160
|
+
onMounted(() => {
|
|
1161
|
+
const refs = this.refs;
|
|
1162
|
+
const length = refs.length;
|
|
1163
|
+
for (let i = 0; i < length; i++) refs[i].bind(this.instance);
|
|
1164
|
+
return () => {
|
|
1165
|
+
const refs = this.refs;
|
|
1166
|
+
const length = refs.length;
|
|
1167
|
+
for (let i = 0; i < length; i++) refs[i].unBind(this.instance);
|
|
1168
|
+
};
|
|
1169
|
+
});
|
|
1170
|
+
}
|
|
1171
|
+
componentSetupStack.pop();
|
|
1172
|
+
pushDepContext(this.listener);
|
|
1173
|
+
const template = this.instance.$render();
|
|
1174
|
+
popDepContext();
|
|
1175
|
+
update(template, this.instance.$portalHost);
|
|
1176
|
+
this.rendered();
|
|
1177
|
+
}
|
|
1178
|
+
updateProps(newProps) {
|
|
1179
|
+
const oldProps = this.rawProps;
|
|
1180
|
+
this.rawProps = newProps;
|
|
1181
|
+
const newRefs = toRefs(newProps.ref);
|
|
1182
|
+
comparePropsWithCallbacks(oldProps, newProps, (key) => {
|
|
1183
|
+
internalWrite(() => {
|
|
1184
|
+
Reflect.deleteProperty(oldProps, key);
|
|
1185
|
+
});
|
|
1186
|
+
}, (key, value) => {
|
|
1187
|
+
internalWrite(() => {
|
|
1188
|
+
this.props[key] = value;
|
|
1189
|
+
});
|
|
1190
|
+
}, (key, value) => {
|
|
1191
|
+
internalWrite(() => {
|
|
1192
|
+
this.props[key] = value;
|
|
1193
|
+
});
|
|
1194
|
+
});
|
|
1195
|
+
if (this.refs) {
|
|
1196
|
+
const len = this.refs.length;
|
|
1197
|
+
for (let i = 0; i < len; i++) {
|
|
1198
|
+
const oldRef = this.refs[i];
|
|
1199
|
+
if (!newRefs.includes(oldRef)) oldRef.unBind(this.instance);
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
const len = newRefs.length;
|
|
1203
|
+
for (let i = 0; i < len; i++) newRefs[i].bind(this.instance);
|
|
1204
|
+
if (len) this.refs = newRefs;
|
|
1205
|
+
}
|
|
1206
|
+
canUpdate(oldProps, newProps) {
|
|
1207
|
+
if (typeof this.instance.$useMemo === "function") {
|
|
1208
|
+
if (this.instance.$useMemo(newProps, oldProps)) return false;
|
|
1209
|
+
}
|
|
1210
|
+
return true;
|
|
1211
|
+
}
|
|
1212
|
+
rerender() {
|
|
1213
|
+
this.listener.destroy();
|
|
1214
|
+
pushDepContext(this.listener);
|
|
1215
|
+
const template = this.instance.$render();
|
|
1216
|
+
popDepContext();
|
|
1217
|
+
return template;
|
|
1218
|
+
}
|
|
1219
|
+
destroy() {
|
|
1220
|
+
this.listener.destroy();
|
|
1221
|
+
if (this.updatedDestroyCallbacks) this.updatedDestroyCallbacks.forEach((fn) => {
|
|
1222
|
+
fn();
|
|
1223
|
+
});
|
|
1224
|
+
if (this.unmountedCallbacks) this.unmountedCallbacks.forEach((fn) => {
|
|
1225
|
+
fn();
|
|
1226
|
+
});
|
|
1227
|
+
this.parentComponent = this.updatedDestroyCallbacks = this.mountCallbacks = this.updatedCallbacks = this.unmountedCallbacks = null;
|
|
1228
|
+
}
|
|
1229
|
+
rendered() {
|
|
1230
|
+
this.changedSubComponents.clear();
|
|
1231
|
+
const is = this.isFirstRendering;
|
|
1232
|
+
this.isFirstRendering = false;
|
|
1233
|
+
this._dirty = this._changed = false;
|
|
1234
|
+
this.invokeUpdatedHooks();
|
|
1235
|
+
if (is) this.invokeMountHooks();
|
|
1236
|
+
if (this.changed) Promise.resolve().then(() => {
|
|
1237
|
+
if (this.parentComponent) this.parentComponent.markAsChanged(this);
|
|
1238
|
+
});
|
|
1239
|
+
}
|
|
1240
|
+
invokeMountHooks() {
|
|
1241
|
+
const unmountedCallbacks = [];
|
|
1242
|
+
if (this.mountCallbacks) {
|
|
1243
|
+
const len = this.mountCallbacks.length;
|
|
1244
|
+
for (let i = 0; i < len; ++i) {
|
|
1245
|
+
const fn = this.mountCallbacks[i];
|
|
1246
|
+
const destroyFn = fn();
|
|
1247
|
+
if (typeof destroyFn === "function") unmountedCallbacks.push(destroyFn);
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
if (unmountedCallbacks.length) if (this.unmountedCallbacks) this.unmountedCallbacks.push(...unmountedCallbacks);
|
|
1251
|
+
else this.unmountedCallbacks = unmountedCallbacks;
|
|
1252
|
+
this.mountCallbacks = null;
|
|
1253
|
+
}
|
|
1254
|
+
invokeUpdatedHooks() {
|
|
1255
|
+
if (this.updatedCallbacks) {
|
|
1256
|
+
if (this.updatedDestroyCallbacks) this.updatedDestroyCallbacks.forEach((fn) => {
|
|
1257
|
+
fn();
|
|
1258
|
+
});
|
|
1259
|
+
const updatedDestroyCallbacks = [];
|
|
1260
|
+
const len = this.updatedCallbacks.length;
|
|
1261
|
+
for (let i = 0; i < len; ++i) {
|
|
1262
|
+
const fn = this.updatedCallbacks[i];
|
|
1263
|
+
const destroyFn = fn();
|
|
1264
|
+
if (typeof destroyFn === "function") updatedDestroyCallbacks.push(destroyFn);
|
|
1265
|
+
}
|
|
1266
|
+
this.updatedDestroyCallbacks = updatedDestroyCallbacks.length ? updatedDestroyCallbacks : null;
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
};
|
|
1270
|
+
/**
|
|
1271
|
+
* 获取当前组件实例
|
|
1272
|
+
*/
|
|
1273
|
+
function getCurrentInstance() {
|
|
1274
|
+
return getSetupContext();
|
|
1275
|
+
}
|
|
1276
|
+
function registryComponentDestroyCallback(fn) {
|
|
1277
|
+
const component = getSetupContext(false);
|
|
1278
|
+
if (component) {
|
|
1279
|
+
if (!component.unmountedCallbacks) component.unmountedCallbacks = [];
|
|
1280
|
+
component.unmountedCallbacks.push(fn);
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
//#endregion
|
|
1284
|
+
//#region src/base/jsx-element.ts
|
|
1285
|
+
function Fragment(props) {
|
|
1286
|
+
return () => {
|
|
1287
|
+
return props.children;
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
function jsx(type, props, key) {
|
|
1291
|
+
return JSXNodeFactory.createNode(type, props, key);
|
|
1292
|
+
}
|
|
1293
|
+
var jsxs = jsx;
|
|
1294
|
+
var JSXNodeFactory = { createNode(type, props, key) {
|
|
1295
|
+
return {
|
|
1296
|
+
type,
|
|
1297
|
+
props,
|
|
1298
|
+
key
|
|
1299
|
+
};
|
|
1300
|
+
} };
|
|
1301
|
+
/**
|
|
1302
|
+
* 给组件的视图元素节点添加自定义属性标记
|
|
1303
|
+
* @param marks
|
|
1304
|
+
* @param setup
|
|
1305
|
+
* @example
|
|
1306
|
+
* ```tsx
|
|
1307
|
+
* const App = withMark('mark', function(props) {
|
|
1308
|
+
* return () => {
|
|
1309
|
+
* return <div>...</div>
|
|
1310
|
+
* }
|
|
1311
|
+
* })
|
|
1312
|
+
* ```
|
|
1313
|
+
*/
|
|
1314
|
+
function withMark(marks, setup) {
|
|
1315
|
+
if (!marks) return setup;
|
|
1316
|
+
return function(props) {
|
|
1317
|
+
const componentRenderFn = setup(props);
|
|
1318
|
+
if (typeof componentRenderFn === "function") return function() {
|
|
1319
|
+
return applyMark(marks, componentRenderFn);
|
|
1320
|
+
};
|
|
1321
|
+
const oldRender = componentRenderFn.$render;
|
|
1322
|
+
componentRenderFn.$render = function() {
|
|
1323
|
+
return applyMark(marks, () => {
|
|
1324
|
+
return oldRender.call(componentRenderFn);
|
|
1325
|
+
});
|
|
1326
|
+
};
|
|
1327
|
+
return componentRenderFn;
|
|
1328
|
+
};
|
|
1329
|
+
}
|
|
1330
|
+
/**
|
|
1331
|
+
* 内部使用
|
|
1332
|
+
* @internal
|
|
1333
|
+
* @param mark
|
|
1334
|
+
* @param render
|
|
1335
|
+
*/
|
|
1336
|
+
function applyMark(mark, render) {
|
|
1337
|
+
const oldCreateNote = JSXNodeFactory.createNode;
|
|
1338
|
+
const spaces = Array.isArray(mark) ? mark : [mark];
|
|
1339
|
+
JSXNodeFactory.createNode = function(name, props, key) {
|
|
1340
|
+
for (const scopedId of spaces) props[scopedId] = "";
|
|
1341
|
+
return oldCreateNote.apply(JSXNodeFactory, [
|
|
1342
|
+
name,
|
|
1343
|
+
props,
|
|
1344
|
+
key
|
|
1345
|
+
]);
|
|
1346
|
+
};
|
|
1347
|
+
const vDom = render();
|
|
1348
|
+
JSXNodeFactory.createNode = oldCreateNote;
|
|
1349
|
+
return vDom;
|
|
1350
|
+
}
|
|
1351
|
+
/**
|
|
1352
|
+
* 将子节点渲染到指定节点
|
|
1353
|
+
* @param props
|
|
1354
|
+
* @example
|
|
1355
|
+
* ```tsx
|
|
1356
|
+
* function App() {
|
|
1357
|
+
* const modal = document.getElementById('modal')!
|
|
1358
|
+
* return () => {
|
|
1359
|
+
* return (
|
|
1360
|
+
* <div>
|
|
1361
|
+
* <Portal host={modal}>
|
|
1362
|
+
* 这里的内容将渲染到 modal 节点
|
|
1363
|
+
* </Portal>
|
|
1364
|
+
* </div>
|
|
1365
|
+
* )
|
|
1366
|
+
* }
|
|
1367
|
+
* }
|
|
1368
|
+
* ```
|
|
1369
|
+
*/
|
|
1370
|
+
function Portal(props) {
|
|
1371
|
+
return {
|
|
1372
|
+
$portalHost: props.host,
|
|
1373
|
+
$render() {
|
|
1374
|
+
return props.children;
|
|
1375
|
+
}
|
|
1376
|
+
};
|
|
1377
|
+
}
|
|
1378
|
+
//#endregion
|
|
1379
|
+
//#region src/reactive/watch.ts
|
|
1380
|
+
function watch(trigger, callback) {
|
|
1381
|
+
let prevFn;
|
|
1382
|
+
const dep = new Dep(() => {
|
|
1383
|
+
pushDepContext(dep);
|
|
1384
|
+
const newValue = trigger();
|
|
1385
|
+
popDepContext();
|
|
1386
|
+
if (newValue === oldValue) return;
|
|
1387
|
+
if (prevFn) prevFn();
|
|
1388
|
+
prevFn = callback(newValue, oldValue);
|
|
1389
|
+
oldValue = newValue;
|
|
1390
|
+
});
|
|
1391
|
+
pushDepContext(dep);
|
|
1392
|
+
let oldValue = trigger();
|
|
1393
|
+
popDepContext();
|
|
1394
|
+
dep.destroyCallbacks.push(() => {
|
|
1395
|
+
prevFn?.();
|
|
1396
|
+
});
|
|
1397
|
+
function unWatch() {
|
|
1398
|
+
dep.destroy();
|
|
1399
|
+
}
|
|
1400
|
+
registryComponentDestroyCallback(unWatch);
|
|
1401
|
+
return unWatch;
|
|
1402
|
+
}
|
|
1403
|
+
//#endregion
|
|
1404
|
+
//#region src/base/context.ts
|
|
1405
|
+
var injectMap = /* @__PURE__ */ new WeakMap();
|
|
1406
|
+
function getInjector(start) {
|
|
1407
|
+
while (start) {
|
|
1408
|
+
const injector = injectMap.get(start);
|
|
1409
|
+
if (injector) return injector;
|
|
1410
|
+
start = start.parentComponent;
|
|
1411
|
+
}
|
|
1412
|
+
return new NullInjector();
|
|
1413
|
+
}
|
|
1414
|
+
function createContext(providers, scope, parentInjector) {
|
|
1415
|
+
return function context(props) {
|
|
1416
|
+
const instance = getCurrentInstance();
|
|
1417
|
+
const injector = new ReflectiveInjector(parentInjector || getInjector(instance), providers, scope);
|
|
1418
|
+
injectMap.set(instance, injector);
|
|
1419
|
+
return () => {
|
|
1420
|
+
return props.children;
|
|
1421
|
+
};
|
|
1422
|
+
};
|
|
1423
|
+
}
|
|
1424
|
+
function createContextProvider(params) {
|
|
1425
|
+
return function contextProvider(props) {
|
|
1426
|
+
let Context = createContext([{
|
|
1427
|
+
provide: params.provide,
|
|
1428
|
+
...props
|
|
1429
|
+
}]);
|
|
1430
|
+
watch(() => {
|
|
1431
|
+
return props.useClass || props.useFactory || props.useValue || props.useExisting;
|
|
1432
|
+
}, () => {
|
|
1433
|
+
Context = createContext([{
|
|
1434
|
+
provide: params.provide,
|
|
1435
|
+
...props
|
|
1436
|
+
}]);
|
|
1437
|
+
});
|
|
1438
|
+
return () => {
|
|
1439
|
+
return jsx(Context, { children: props.children });
|
|
1440
|
+
};
|
|
1441
|
+
};
|
|
1442
|
+
}
|
|
1443
|
+
/**
|
|
1444
|
+
* 通过组件上下文获取 IoC 容器内数据的勾子方法
|
|
1445
|
+
*/
|
|
1446
|
+
function inject(token, notFoundValue = THROW_IF_NOT_FOUND, flags) {
|
|
1447
|
+
return getInjector(getCurrentInstance()).get(token, notFoundValue, flags);
|
|
1448
|
+
}
|
|
1449
|
+
/**
|
|
1450
|
+
* 给组件添加注解
|
|
1451
|
+
* @param annotation
|
|
1452
|
+
* @param componentSetup
|
|
1453
|
+
* @example
|
|
1454
|
+
* ```ts
|
|
1455
|
+
* export customScope = new Scope('scopeName')
|
|
1456
|
+
* export const App = withAnnotation({
|
|
1457
|
+
* scope: customScope,
|
|
1458
|
+
* providers: [
|
|
1459
|
+
* ExampleService
|
|
1460
|
+
* ]
|
|
1461
|
+
* }, function(props: Props) {
|
|
1462
|
+
* return () => {
|
|
1463
|
+
* return <div>...</div>
|
|
1464
|
+
* }
|
|
1465
|
+
* })
|
|
1466
|
+
* ```
|
|
1467
|
+
*/
|
|
1468
|
+
function withAnnotation(annotation, componentSetup) {
|
|
1469
|
+
return function(props) {
|
|
1470
|
+
const instance = getCurrentInstance();
|
|
1471
|
+
const injector = new ReflectiveInjector(injectMap.get(instance) || getInjector(instance.parentComponent), [{
|
|
1472
|
+
provide: Injector,
|
|
1473
|
+
useFactory() {
|
|
1474
|
+
return injector;
|
|
1475
|
+
}
|
|
1476
|
+
}, ...annotation.providers || []], annotation.scope);
|
|
1477
|
+
injectMap.set(instance, injector);
|
|
1478
|
+
return componentSetup(props);
|
|
1479
|
+
};
|
|
1480
|
+
}
|
|
1481
|
+
//#endregion
|
|
1482
|
+
//#region src/base/injection-tokens.ts
|
|
1483
|
+
var NativeRenderer = class {};
|
|
1484
|
+
//#endregion
|
|
1485
|
+
//#region src/base/memo.ts
|
|
1486
|
+
/**
|
|
1487
|
+
* @deprecated 即将弃用,Viewfly 默认就有 memo 的效果
|
|
1488
|
+
* @param canUseMemo
|
|
1489
|
+
* @param render
|
|
1490
|
+
*/
|
|
1491
|
+
function withMemo(canUseMemo, render) {
|
|
1492
|
+
return {
|
|
1493
|
+
$useMemo: canUseMemo,
|
|
1494
|
+
$render: render
|
|
1495
|
+
};
|
|
1496
|
+
}
|
|
1497
|
+
//#endregion
|
|
1498
|
+
//#region src/base/renderer.ts
|
|
1499
|
+
var listenerReg = /^on[A-Z]/;
|
|
1500
|
+
function createRenderer(component, nativeRenderer, namespace) {
|
|
1501
|
+
let isInit = true;
|
|
1502
|
+
return function render(host) {
|
|
1503
|
+
if (isInit) {
|
|
1504
|
+
isInit = false;
|
|
1505
|
+
componentRender(nativeRenderer, component, {
|
|
1506
|
+
type: ComponentAtomType,
|
|
1507
|
+
index: 0,
|
|
1508
|
+
nodeType: component.type,
|
|
1509
|
+
jsxNode: component,
|
|
1510
|
+
sibling: null,
|
|
1511
|
+
child: null,
|
|
1512
|
+
nativeNode: null,
|
|
1513
|
+
namespace
|
|
1514
|
+
}, {
|
|
1515
|
+
isParent: true,
|
|
1516
|
+
host,
|
|
1517
|
+
rootHost: host
|
|
1518
|
+
});
|
|
1519
|
+
} else deepUpdateByComponentDirtyTree(nativeRenderer, component, false);
|
|
1520
|
+
};
|
|
1521
|
+
}
|
|
1522
|
+
function buildView(nativeRenderer, parentComponent, atom, context) {
|
|
1523
|
+
const { jsxNode, type } = atom;
|
|
1524
|
+
if (type === ComponentAtomType) {
|
|
1525
|
+
const component = new Component(parentComponent, jsxNode.type, jsxNode.props, jsxNode.key);
|
|
1526
|
+
atom.jsxNode = component;
|
|
1527
|
+
componentRender(nativeRenderer, component, atom, context);
|
|
1528
|
+
} else if (type === ElementAtomType) createElement(nativeRenderer, atom, parentComponent, context);
|
|
1529
|
+
else createTextNode(nativeRenderer, atom, context);
|
|
1530
|
+
}
|
|
1531
|
+
function buildElementChildren(atom, nativeRenderer, parentComponent, context) {
|
|
1532
|
+
let child = atom.child;
|
|
1533
|
+
while (child) {
|
|
1534
|
+
buildView(nativeRenderer, parentComponent, child, context);
|
|
1535
|
+
child = child.sibling;
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
function patchComponent(nativeRenderer, component, oldChildAtom, newAtom, context, needMove) {
|
|
1539
|
+
newAtom.child = createChildChain(component.rerender(), nativeRenderer, newAtom.namespace);
|
|
1540
|
+
diff(nativeRenderer, component, newAtom.child, oldChildAtom, context, needMove);
|
|
1541
|
+
}
|
|
1542
|
+
function deepUpdateByComponentDirtyTree(nativeRenderer, component, needMove) {
|
|
1543
|
+
if (component.dirty) {
|
|
1544
|
+
if (component.canUpdate(component.props, component.props)) {
|
|
1545
|
+
const { atom, host, isParent, rootHost } = component.viewMetadata;
|
|
1546
|
+
const context = {
|
|
1547
|
+
host,
|
|
1548
|
+
isParent,
|
|
1549
|
+
rootHost
|
|
1550
|
+
};
|
|
1551
|
+
const diffAtom = atom.child;
|
|
1552
|
+
patchComponent(nativeRenderer, component, diffAtom, atom, context, needMove);
|
|
1553
|
+
const next = atom.sibling;
|
|
1554
|
+
if (next && next.jsxNode instanceof Component) {
|
|
1555
|
+
const view = next.jsxNode.viewMetadata;
|
|
1556
|
+
view.host = context.host;
|
|
1557
|
+
view.isParent = context.isParent;
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
component.rendered();
|
|
1561
|
+
} else if (component.changed) {
|
|
1562
|
+
component.changedSubComponents.forEach((child) => {
|
|
1563
|
+
deepUpdateByComponentDirtyTree(nativeRenderer, child, needMove);
|
|
1564
|
+
});
|
|
1565
|
+
component.rendered();
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, needMove) {
|
|
1569
|
+
const commits = [];
|
|
1570
|
+
while (newAtom) {
|
|
1571
|
+
oldAtom = createChanges(newAtom, oldAtom, commits);
|
|
1572
|
+
newAtom = newAtom.sibling;
|
|
1573
|
+
}
|
|
1574
|
+
let dirtyDiffAtom = oldAtom;
|
|
1575
|
+
while (dirtyDiffAtom) {
|
|
1576
|
+
cleanView(nativeRenderer, dirtyDiffAtom, true);
|
|
1577
|
+
dirtyDiffAtom = dirtyDiffAtom.sibling;
|
|
1578
|
+
}
|
|
1579
|
+
let offset = 0;
|
|
1580
|
+
const len = commits.length;
|
|
1581
|
+
for (let i = 0; i < len; i++) {
|
|
1582
|
+
while (oldAtom) {
|
|
1583
|
+
if (oldAtom.index <= i) {
|
|
1584
|
+
offset--;
|
|
1585
|
+
oldAtom = oldAtom.sibling;
|
|
1586
|
+
continue;
|
|
1587
|
+
}
|
|
1588
|
+
break;
|
|
1589
|
+
}
|
|
1590
|
+
const { dirtyAtom, newAtom } = commits[i];
|
|
1591
|
+
if (dirtyAtom) switch (dirtyAtom.type) {
|
|
1592
|
+
case ElementAtomType:
|
|
1593
|
+
updateElement(nativeRenderer, context, parentComponent, offset, needMove, newAtom, dirtyAtom);
|
|
1594
|
+
break;
|
|
1595
|
+
case TextAtomType:
|
|
1596
|
+
updateText(nativeRenderer, context, offset, needMove, newAtom, dirtyAtom);
|
|
1597
|
+
break;
|
|
1598
|
+
case ComponentAtomType:
|
|
1599
|
+
updateComponent(nativeRenderer, context, offset, needMove, newAtom, dirtyAtom);
|
|
1600
|
+
break;
|
|
1601
|
+
}
|
|
1602
|
+
else {
|
|
1603
|
+
buildView(nativeRenderer, parentComponent, newAtom, context);
|
|
1604
|
+
offset++;
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
function createChanges(newAtom, oldAtom, commits) {
|
|
1609
|
+
const startDiffAtom = oldAtom;
|
|
1610
|
+
let prev = null;
|
|
1611
|
+
while (oldAtom) {
|
|
1612
|
+
if (oldAtom.type === newAtom.type && oldAtom.nodeType === newAtom.nodeType && oldAtom.key === newAtom.key) {
|
|
1613
|
+
commits.push({
|
|
1614
|
+
dirtyAtom: oldAtom,
|
|
1615
|
+
newAtom
|
|
1616
|
+
});
|
|
1617
|
+
const next = oldAtom.sibling;
|
|
1618
|
+
if (!prev) return next;
|
|
1619
|
+
prev.sibling = next;
|
|
1620
|
+
return startDiffAtom;
|
|
1621
|
+
}
|
|
1622
|
+
prev = oldAtom;
|
|
1623
|
+
oldAtom = oldAtom.sibling;
|
|
1624
|
+
}
|
|
1625
|
+
commits.push({
|
|
1626
|
+
dirtyAtom: null,
|
|
1627
|
+
newAtom
|
|
1628
|
+
});
|
|
1629
|
+
return startDiffAtom;
|
|
1630
|
+
}
|
|
1631
|
+
function updateText(nativeRenderer, context, offset, needMove, newAtom, oldAtom) {
|
|
1632
|
+
const nativeNode = oldAtom.nativeNode;
|
|
1633
|
+
newAtom.nativeNode = nativeNode;
|
|
1634
|
+
if (needMove || newAtom.index - offset !== oldAtom.index) insertNode(nativeRenderer, newAtom, context);
|
|
1635
|
+
context.host = nativeNode;
|
|
1636
|
+
context.isParent = false;
|
|
1637
|
+
}
|
|
1638
|
+
function updateElement(nativeRenderer, context, parentComponent, offset, needMove, newAtom, oldAtom) {
|
|
1639
|
+
const nativeNode = oldAtom.nativeNode;
|
|
1640
|
+
newAtom.nativeNode = nativeNode;
|
|
1641
|
+
if (needMove || newAtom.index - offset !== oldAtom.index) insertNode(nativeRenderer, newAtom, context);
|
|
1642
|
+
context.host = nativeNode;
|
|
1643
|
+
context.isParent = false;
|
|
1644
|
+
updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComponent, {
|
|
1645
|
+
host: nativeNode,
|
|
1646
|
+
isParent: true,
|
|
1647
|
+
rootHost: context.rootHost
|
|
1648
|
+
});
|
|
1649
|
+
}
|
|
1650
|
+
function updateComponent(nativeRenderer, context, offset, needMove, newAtom, oldAtom) {
|
|
1651
|
+
const component = oldAtom.jsxNode;
|
|
1652
|
+
const portalHost = component.instance.$portalHost;
|
|
1653
|
+
context = portalHost ? {
|
|
1654
|
+
isParent: true,
|
|
1655
|
+
host: portalHost,
|
|
1656
|
+
rootHost: portalHost
|
|
1657
|
+
} : context;
|
|
1658
|
+
component.viewMetadata = {
|
|
1659
|
+
atom: newAtom,
|
|
1660
|
+
...context
|
|
1661
|
+
};
|
|
1662
|
+
const newProps = newAtom.jsxNode.props;
|
|
1663
|
+
newAtom.jsxNode = component;
|
|
1664
|
+
needMove = needMove || newAtom.index - offset !== oldAtom.index;
|
|
1665
|
+
const canUpdate = component.canUpdate(component.props, newProps);
|
|
1666
|
+
const propsIsChanged = hasChange(newProps, component.props);
|
|
1667
|
+
if (propsIsChanged) component.updateProps(newProps);
|
|
1668
|
+
if (canUpdate && (propsIsChanged || component.dirty)) {
|
|
1669
|
+
patchComponent(nativeRenderer, component, oldAtom.child, newAtom, context, needMove);
|
|
1670
|
+
const next = oldAtom.sibling;
|
|
1671
|
+
if (next && next.jsxNode instanceof Component) {
|
|
1672
|
+
const view = next.jsxNode.viewMetadata;
|
|
1673
|
+
view.host = context.host;
|
|
1674
|
+
view.isParent = context.isParent;
|
|
1675
|
+
}
|
|
1676
|
+
} else {
|
|
1677
|
+
newAtom.child = oldAtom.child;
|
|
1678
|
+
reuseComponentView(nativeRenderer, newAtom.child, context, needMove, !canUpdate || !component.changedSubComponents.size);
|
|
1679
|
+
}
|
|
1680
|
+
component.rendered();
|
|
1681
|
+
}
|
|
1682
|
+
function reuseComponentView(nativeRenderer, child, context, moveView, skipSubComponentDiff) {
|
|
1683
|
+
const updateContext = (atom) => {
|
|
1684
|
+
const jsxNode = atom.jsxNode;
|
|
1685
|
+
if (jsxNode instanceof Component) {
|
|
1686
|
+
reuseComponentView(nativeRenderer, atom.child, context, moveView, skipSubComponentDiff);
|
|
1687
|
+
if (!skipSubComponentDiff) deepUpdateByComponentDirtyTree(nativeRenderer, jsxNode, moveView);
|
|
1688
|
+
} else {
|
|
1689
|
+
if (moveView) insertNode(nativeRenderer, atom, context);
|
|
1690
|
+
if (!skipSubComponentDiff) reuseElementChildrenView(nativeRenderer, atom, context);
|
|
1691
|
+
context.isParent = false;
|
|
1692
|
+
context.host = atom.nativeNode;
|
|
1693
|
+
}
|
|
1694
|
+
};
|
|
1695
|
+
while (child) {
|
|
1696
|
+
updateContext(child);
|
|
1697
|
+
child = child.sibling;
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
function reuseElementChildrenView(nativeRenderer, atom, context) {
|
|
1701
|
+
let child = atom.child;
|
|
1702
|
+
while (child) {
|
|
1703
|
+
if (child.jsxNode instanceof Component) deepUpdateByComponentDirtyTree(nativeRenderer, child.jsxNode, false);
|
|
1704
|
+
else reuseElementChildrenView(nativeRenderer, child, context);
|
|
1705
|
+
child = child.sibling;
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
function cleanElementChildren(atom, nativeRenderer) {
|
|
1709
|
+
let child = atom.child;
|
|
1710
|
+
nativeRenderer.cleanChildren(atom.nativeNode, atom.namespace);
|
|
1711
|
+
while (child) {
|
|
1712
|
+
cleanView(nativeRenderer, child, false);
|
|
1713
|
+
child = child.sibling;
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
function cleanView(nativeRenderer, atom, needClean) {
|
|
1717
|
+
if (atom.type === ComponentAtomType) {
|
|
1718
|
+
const jsxNode = atom.jsxNode;
|
|
1719
|
+
if (jsxNode.instance.$portalHost) needClean = true;
|
|
1720
|
+
cleanChildren(atom, nativeRenderer, needClean);
|
|
1721
|
+
jsxNode.destroy();
|
|
1722
|
+
return;
|
|
1723
|
+
}
|
|
1724
|
+
if (needClean) {
|
|
1725
|
+
nativeRenderer.remove(atom.nativeNode, atom.namespace);
|
|
1726
|
+
needClean = false;
|
|
1727
|
+
}
|
|
1728
|
+
if (atom.type === ElementAtomType) {
|
|
1729
|
+
const ref = atom.jsxNode.props["ref"];
|
|
1730
|
+
applyRefs(ref, atom.nativeNode, false);
|
|
1731
|
+
}
|
|
1732
|
+
cleanChildren(atom, nativeRenderer, needClean);
|
|
1733
|
+
}
|
|
1734
|
+
function cleanChildren(atom, nativeRenderer, needClean) {
|
|
1735
|
+
let child = atom.child;
|
|
1736
|
+
while (child) {
|
|
1737
|
+
cleanView(nativeRenderer, child, needClean);
|
|
1738
|
+
child = child.sibling;
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
function componentRender(nativeRenderer, component, from, context) {
|
|
1742
|
+
component.render((template, portalHost) => {
|
|
1743
|
+
from.child = createChildChain(template, nativeRenderer, from.namespace);
|
|
1744
|
+
context = portalHost ? {
|
|
1745
|
+
isParent: true,
|
|
1746
|
+
host: portalHost,
|
|
1747
|
+
rootHost: portalHost
|
|
1748
|
+
} : context;
|
|
1749
|
+
component.viewMetadata = {
|
|
1750
|
+
atom: from,
|
|
1751
|
+
...context
|
|
1752
|
+
};
|
|
1753
|
+
let child = from.child;
|
|
1754
|
+
while (child) {
|
|
1755
|
+
buildView(nativeRenderer, component, child, context);
|
|
1756
|
+
child = child.sibling;
|
|
1757
|
+
}
|
|
1758
|
+
});
|
|
1759
|
+
}
|
|
1760
|
+
function createChainByJSXNode(type, jsxNode, nodeType, prevAtom, namespace, key) {
|
|
1761
|
+
const atom = {
|
|
1762
|
+
type,
|
|
1763
|
+
index: prevAtom.index + 1,
|
|
1764
|
+
jsxNode,
|
|
1765
|
+
sibling: null,
|
|
1766
|
+
child: null,
|
|
1767
|
+
nativeNode: null,
|
|
1768
|
+
namespace,
|
|
1769
|
+
nodeType,
|
|
1770
|
+
key
|
|
1771
|
+
};
|
|
1772
|
+
prevAtom.sibling = atom;
|
|
1773
|
+
return atom;
|
|
1774
|
+
}
|
|
1775
|
+
function createChainByNode(jsxNode, prevAtom, nativeRenderer, elementNamespace) {
|
|
1776
|
+
const type = typeof jsxNode;
|
|
1777
|
+
if (jsxNode != null && type !== "boolean") {
|
|
1778
|
+
if (type === "string") return createChainByJSXNode(TextAtomType, jsxNode, jsxNode, prevAtom, elementNamespace);
|
|
1779
|
+
if (type === "object") {
|
|
1780
|
+
if (Array.isArray(jsxNode)) return createChainByChildren(jsxNode, prevAtom, nativeRenderer, elementNamespace);
|
|
1781
|
+
const nodeType = typeof jsxNode.type;
|
|
1782
|
+
if (nodeType === "string") return createChainByJSXNode(ElementAtomType, jsxNode, jsxNode.type, prevAtom, nativeRenderer.getNameSpace(jsxNode.type, elementNamespace), jsxNode.key);
|
|
1783
|
+
else if (nodeType === "function") return createChainByJSXNode(ComponentAtomType, jsxNode, jsxNode.type, prevAtom, elementNamespace, jsxNode.key);
|
|
1784
|
+
}
|
|
1785
|
+
const text = String(jsxNode);
|
|
1786
|
+
return createChainByJSXNode(TextAtomType, text, text, prevAtom, elementNamespace);
|
|
1787
|
+
}
|
|
1788
|
+
return prevAtom;
|
|
1789
|
+
}
|
|
1790
|
+
function createChainByChildren(children, prevAtom, nativeRenderer, elementNamespace) {
|
|
1791
|
+
const len = children.length;
|
|
1792
|
+
for (let i = 0; i < len; i++) {
|
|
1793
|
+
const item = children[i];
|
|
1794
|
+
prevAtom = createChainByNode(item, prevAtom, nativeRenderer, elementNamespace);
|
|
1795
|
+
}
|
|
1796
|
+
return prevAtom;
|
|
1797
|
+
}
|
|
1798
|
+
function createChildChain(template, nativeRenderer, namespace) {
|
|
1799
|
+
const beforeAtom = {
|
|
1800
|
+
sibling: null,
|
|
1801
|
+
index: -1
|
|
1802
|
+
};
|
|
1803
|
+
createChainByNode(template, beforeAtom, nativeRenderer, namespace);
|
|
1804
|
+
return beforeAtom.sibling;
|
|
1805
|
+
}
|
|
1806
|
+
function insertNode(nativeRenderer, atom, context) {
|
|
1807
|
+
if (context.isParent) if (context.host === context.rootHost) nativeRenderer.appendChild(context.host, atom.nativeNode, atom.namespace);
|
|
1808
|
+
else nativeRenderer.prependChild(context.host, atom.nativeNode, atom.namespace);
|
|
1809
|
+
else nativeRenderer.insertAfter(atom.nativeNode, context.host, atom.namespace);
|
|
1810
|
+
}
|
|
1811
|
+
function createElementChildren(type, children, nativeRenderer, namespace) {
|
|
1812
|
+
return createChildChain(children, nativeRenderer, nativeRenderer.getNameSpace(type, namespace));
|
|
1813
|
+
}
|
|
1814
|
+
function createElement(nativeRenderer, atom, parentComponent, context) {
|
|
1815
|
+
const { namespace, jsxNode } = atom;
|
|
1816
|
+
const nativeNode = nativeRenderer.createElement(jsxNode.type, namespace);
|
|
1817
|
+
const props = jsxNode.props;
|
|
1818
|
+
let bindingRefs;
|
|
1819
|
+
for (const key in props) {
|
|
1820
|
+
if (key === "children") {
|
|
1821
|
+
atom.child = createElementChildren(jsxNode.type, props.children, nativeRenderer, namespace);
|
|
1822
|
+
continue;
|
|
1823
|
+
}
|
|
1824
|
+
if (key === "class") {
|
|
1825
|
+
const className = classToString(props[key]);
|
|
1826
|
+
if (className) nativeRenderer.setClass(nativeNode, className, namespace);
|
|
1827
|
+
continue;
|
|
1828
|
+
}
|
|
1829
|
+
if (key === "style") {
|
|
1830
|
+
const style = styleToObject(props.style);
|
|
1831
|
+
for (const key in style) nativeRenderer.setStyle(nativeNode, key, style[key], namespace);
|
|
1832
|
+
continue;
|
|
1833
|
+
}
|
|
1834
|
+
if (listenerReg.test(key)) {
|
|
1835
|
+
const listener = props[key];
|
|
1836
|
+
if (typeof listener === "function") nativeRenderer.listen(nativeNode, key, listener, namespace);
|
|
1837
|
+
continue;
|
|
1838
|
+
}
|
|
1839
|
+
if (key === "ref") {
|
|
1840
|
+
bindingRefs = props[key];
|
|
1841
|
+
continue;
|
|
1842
|
+
}
|
|
1843
|
+
nativeRenderer.setProperty(nativeNode, key, props[key], namespace);
|
|
1844
|
+
}
|
|
1845
|
+
atom.nativeNode = nativeNode;
|
|
1846
|
+
insertNode(nativeRenderer, atom, context);
|
|
1847
|
+
buildElementChildren(atom, nativeRenderer, parentComponent, {
|
|
1848
|
+
isParent: true,
|
|
1849
|
+
host: nativeNode,
|
|
1850
|
+
rootHost: context.rootHost
|
|
1851
|
+
});
|
|
1852
|
+
context.host = nativeNode;
|
|
1853
|
+
context.isParent = false;
|
|
1854
|
+
applyRefs(bindingRefs, nativeNode, true);
|
|
1855
|
+
}
|
|
1856
|
+
function createTextNode(nativeRenderer, atom, context) {
|
|
1857
|
+
const nativeNode = nativeRenderer.createTextNode(atom.jsxNode, atom.namespace);
|
|
1858
|
+
atom.nativeNode = nativeNode;
|
|
1859
|
+
insertNode(nativeRenderer, atom, context);
|
|
1860
|
+
context.host = nativeNode;
|
|
1861
|
+
context.isParent = false;
|
|
1862
|
+
}
|
|
1863
|
+
function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComponent, context) {
|
|
1864
|
+
const newVNode = newAtom.jsxNode;
|
|
1865
|
+
const isSvg = newAtom.namespace;
|
|
1866
|
+
const nativeNode = newAtom.nativeNode;
|
|
1867
|
+
const oldVNode = oldAtom.jsxNode;
|
|
1868
|
+
if (newVNode === oldVNode) {
|
|
1869
|
+
newAtom.child = oldAtom.child;
|
|
1870
|
+
reuseElementChildrenView(nativeRenderer, newAtom, context);
|
|
1871
|
+
return;
|
|
1872
|
+
}
|
|
1873
|
+
let unBindRefs;
|
|
1874
|
+
let bindRefs;
|
|
1875
|
+
let updatedChildren = false;
|
|
1876
|
+
comparePropsWithCallbacks(oldVNode.props, newVNode.props, (key, oldValue) => {
|
|
1877
|
+
if (key === "children") {
|
|
1878
|
+
updatedChildren = true;
|
|
1879
|
+
cleanElementChildren(oldAtom, nativeRenderer);
|
|
1880
|
+
return;
|
|
1881
|
+
}
|
|
1882
|
+
if (key === "class") {
|
|
1883
|
+
nativeRenderer.setClass(nativeNode, "", isSvg);
|
|
1884
|
+
return;
|
|
1885
|
+
}
|
|
1886
|
+
if (key === "style") {
|
|
1887
|
+
for (const styleName in styleToObject(oldValue)) nativeRenderer.removeStyle(nativeNode, styleName, isSvg);
|
|
1888
|
+
return;
|
|
1889
|
+
}
|
|
1890
|
+
if (listenerReg.test(key)) {
|
|
1891
|
+
if (typeof oldValue === "function") nativeRenderer.unListen(nativeNode, key, oldValue, isSvg);
|
|
1892
|
+
return;
|
|
1893
|
+
}
|
|
1894
|
+
if (key === "ref") {
|
|
1895
|
+
unBindRefs = oldValue;
|
|
1896
|
+
return;
|
|
1897
|
+
}
|
|
1898
|
+
nativeRenderer.removeProperty(nativeNode, key, isSvg);
|
|
1899
|
+
}, (key, value) => {
|
|
1900
|
+
if (key === "children") {
|
|
1901
|
+
updatedChildren = true;
|
|
1902
|
+
newAtom.child = createElementChildren(newVNode.type, value, nativeRenderer, isSvg);
|
|
1903
|
+
buildElementChildren(newAtom, nativeRenderer, parentComponent, context);
|
|
1904
|
+
return;
|
|
1905
|
+
}
|
|
1906
|
+
if (key === "class") {
|
|
1907
|
+
nativeRenderer.setClass(nativeNode, classToString(value), isSvg);
|
|
1908
|
+
return;
|
|
1909
|
+
}
|
|
1910
|
+
if (key === "style") {
|
|
1911
|
+
const styleObj = styleToObject(value);
|
|
1912
|
+
for (const styleName in styleObj) nativeRenderer.setStyle(nativeNode, styleName, styleObj[styleName], isSvg);
|
|
1913
|
+
return;
|
|
1914
|
+
}
|
|
1915
|
+
if (listenerReg.test(key)) {
|
|
1916
|
+
if (typeof value === "function") nativeRenderer.listen(nativeNode, key, value, isSvg);
|
|
1917
|
+
return;
|
|
1918
|
+
}
|
|
1919
|
+
if (key === "ref") {
|
|
1920
|
+
bindRefs = value;
|
|
1921
|
+
return;
|
|
1922
|
+
}
|
|
1923
|
+
nativeRenderer.setProperty(nativeNode, key, value, isSvg);
|
|
1924
|
+
}, (key, newValue, oldValue) => {
|
|
1925
|
+
if (key === "children") {
|
|
1926
|
+
updatedChildren = true;
|
|
1927
|
+
newAtom.child = createElementChildren(newVNode.type, newValue, nativeRenderer, isSvg);
|
|
1928
|
+
if (!newAtom.child) cleanElementChildren(oldAtom, nativeRenderer);
|
|
1929
|
+
else if (!oldAtom.child) buildElementChildren(newAtom, nativeRenderer, parentComponent, context);
|
|
1930
|
+
else diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, context, false);
|
|
1931
|
+
return;
|
|
1932
|
+
}
|
|
1933
|
+
if (key === "class") {
|
|
1934
|
+
const oldClassName = classToString(oldValue);
|
|
1935
|
+
const newClassName = classToString(newValue);
|
|
1936
|
+
if (oldClassName !== newClassName) nativeRenderer.setClass(nativeNode, newClassName, isSvg);
|
|
1937
|
+
return;
|
|
1938
|
+
}
|
|
1939
|
+
if (key === "style") {
|
|
1940
|
+
comparePropsWithCallbacks(styleToObject(oldValue), styleToObject(newValue), (styleName) => {
|
|
1941
|
+
nativeRenderer.removeStyle(nativeNode, styleName, isSvg);
|
|
1942
|
+
}, (styleName, styleValue) => {
|
|
1943
|
+
nativeRenderer.setStyle(nativeNode, styleName, styleValue, isSvg);
|
|
1944
|
+
}, (styleName, styleValue) => {
|
|
1945
|
+
nativeRenderer.setStyle(nativeNode, styleName, styleValue, isSvg);
|
|
1946
|
+
});
|
|
1947
|
+
return;
|
|
1948
|
+
}
|
|
1949
|
+
if (listenerReg.test(key)) {
|
|
1950
|
+
nativeRenderer.unListen(nativeNode, key, oldValue, isSvg);
|
|
1951
|
+
nativeRenderer.listen(nativeNode, key, newValue, isSvg);
|
|
1952
|
+
return;
|
|
1953
|
+
}
|
|
1954
|
+
if (key === "ref") {
|
|
1955
|
+
unBindRefs = oldValue;
|
|
1956
|
+
bindRefs = newValue;
|
|
1957
|
+
return;
|
|
1958
|
+
}
|
|
1959
|
+
nativeRenderer.setProperty(nativeNode, key, newValue, isSvg);
|
|
1960
|
+
});
|
|
1961
|
+
if (!updatedChildren) newAtom.child = oldAtom.child;
|
|
1962
|
+
applyRefs(unBindRefs, nativeNode, false);
|
|
1963
|
+
applyRefs(bindRefs, nativeNode, true);
|
|
1964
|
+
}
|
|
1965
|
+
function applyRefs(refs, nativeNode, binding) {
|
|
1966
|
+
if (refs) {
|
|
1967
|
+
const refList = Array.isArray(refs) ? refs : [refs];
|
|
1968
|
+
const len = refList.length;
|
|
1969
|
+
for (let i = 0; i < len; i++) {
|
|
1970
|
+
const item = refList[i];
|
|
1971
|
+
if (item instanceof DynamicRef) if (binding) item.bind(nativeNode);
|
|
1972
|
+
else item.unBind(nativeNode);
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1976
|
+
//#endregion
|
|
1977
|
+
//#region src/base/root.component.ts
|
|
1978
|
+
/**
|
|
1979
|
+
* Viewfly 根组件,用于实现组件状态更新事件通知
|
|
1980
|
+
*/
|
|
1981
|
+
var RootComponent = class extends Component {
|
|
1982
|
+
constructor(factory, refresh) {
|
|
1983
|
+
super(null, factory, {});
|
|
1984
|
+
this.refresh = refresh;
|
|
1985
|
+
}
|
|
1986
|
+
markAsChanged(changedComponent) {
|
|
1987
|
+
this._changed = true;
|
|
1988
|
+
if (changedComponent) this.changedSubComponents.add(changedComponent);
|
|
1989
|
+
this.refresh();
|
|
1990
|
+
}
|
|
1991
|
+
};
|
|
1992
|
+
//#endregion
|
|
1993
|
+
//#region src/viewfly.ts
|
|
1994
|
+
var viewflyErrorFn = makeError("Viewfly");
|
|
1995
|
+
function viewfly(config) {
|
|
1996
|
+
const { context, nativeRenderer, autoUpdate, root } = Object.assign({ autoUpdate: true }, config);
|
|
1997
|
+
const modules = [];
|
|
1998
|
+
let destroyed = false;
|
|
1999
|
+
let appHost = null;
|
|
2000
|
+
const rootProviders = [];
|
|
2001
|
+
const rootComponent = new RootComponent(() => {
|
|
2002
|
+
const rootContext = createContext(rootProviders, null, context);
|
|
2003
|
+
return () => {
|
|
2004
|
+
return jsx(rootContext, { children: destroyed ? null : root });
|
|
2005
|
+
};
|
|
2006
|
+
}, function() {
|
|
2007
|
+
if (destroyed || !autoUpdate) return;
|
|
2008
|
+
nextTick(() => {
|
|
2009
|
+
render(appHost);
|
|
2010
|
+
});
|
|
2011
|
+
});
|
|
2012
|
+
const render = createRenderer(rootComponent, nativeRenderer, config.elementNamespace);
|
|
2013
|
+
let isStarted = false;
|
|
2014
|
+
let task = null;
|
|
2015
|
+
function nextTick(callback) {
|
|
2016
|
+
if (task !== null) return;
|
|
2017
|
+
task = Promise.resolve().then(() => {
|
|
2018
|
+
task = null;
|
|
2019
|
+
callback();
|
|
2020
|
+
});
|
|
2021
|
+
}
|
|
2022
|
+
const app = {
|
|
2023
|
+
provide(providers) {
|
|
2024
|
+
providers = Array.isArray(providers) ? providers : [providers];
|
|
2025
|
+
rootProviders.push(...providers);
|
|
2026
|
+
return app;
|
|
2027
|
+
},
|
|
2028
|
+
use(module) {
|
|
2029
|
+
if (Array.isArray(module)) modules.push(...module);
|
|
2030
|
+
else modules.push(module);
|
|
2031
|
+
return app;
|
|
2032
|
+
},
|
|
2033
|
+
mount(host) {
|
|
2034
|
+
if (isStarted) throw viewflyErrorFn("application has already started.");
|
|
2035
|
+
for (const module of modules) module.setup?.(app);
|
|
2036
|
+
isStarted = true;
|
|
2037
|
+
appHost = host;
|
|
2038
|
+
render(host);
|
|
2039
|
+
for (const module of modules) module.onAfterStartup?.(app);
|
|
2040
|
+
if (!autoUpdate) return app;
|
|
2041
|
+
return app;
|
|
2042
|
+
},
|
|
2043
|
+
render() {
|
|
2044
|
+
if (appHost) render(appHost);
|
|
2045
|
+
return app;
|
|
2046
|
+
},
|
|
2047
|
+
destroy() {
|
|
2048
|
+
destroyed = true;
|
|
2049
|
+
rootComponent.markAsDirtied();
|
|
2050
|
+
app.render();
|
|
2051
|
+
for (const module of modules) module.onDestroy?.();
|
|
2052
|
+
}
|
|
2053
|
+
};
|
|
2054
|
+
return app;
|
|
2055
|
+
}
|
|
2056
|
+
//#endregion
|
|
2057
|
+
//#region src/reactive/computed.ts
|
|
2058
|
+
function computed(callback, isContinue) {
|
|
2059
|
+
let isStop = false;
|
|
2060
|
+
const dep = new Dep(() => {
|
|
2061
|
+
if (isStop) return;
|
|
2062
|
+
isStop = true;
|
|
2063
|
+
dep.destroy();
|
|
2064
|
+
pushDepContext(dep);
|
|
2065
|
+
const value = callback();
|
|
2066
|
+
popDepContext();
|
|
2067
|
+
internalWrite(() => {
|
|
2068
|
+
proxy.value = value;
|
|
2069
|
+
});
|
|
2070
|
+
canListen(value);
|
|
2071
|
+
isStop = false;
|
|
2072
|
+
});
|
|
2073
|
+
pushDepContext(dep);
|
|
2074
|
+
const value = callback();
|
|
2075
|
+
popDepContext();
|
|
2076
|
+
const proxy = new Proxy({ value }, readonlyProxyHandler);
|
|
2077
|
+
function canListen(value) {
|
|
2078
|
+
if (isContinue) {
|
|
2079
|
+
if (isContinue(value) === false) {
|
|
2080
|
+
dep.destroy();
|
|
2081
|
+
return false;
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
return true;
|
|
2085
|
+
}
|
|
2086
|
+
if (!canListen(value)) return proxy;
|
|
2087
|
+
registryComponentDestroyCallback(() => {
|
|
2088
|
+
dep.destroy();
|
|
2089
|
+
});
|
|
2090
|
+
return proxy;
|
|
2091
|
+
}
|
|
2092
|
+
//#endregion
|
|
2093
|
+
//#region src/reactive/shallow-reactive.ts
|
|
2094
|
+
var defaultShallowObjectReactiveHandler = new ObjectReactiveHandler({
|
|
2095
|
+
readonly: false,
|
|
2096
|
+
shallow: true
|
|
2097
|
+
});
|
|
2098
|
+
var defaultShallowArrayReactiveHandler = new ArrayReactiveHandler({
|
|
2099
|
+
readonly: false,
|
|
2100
|
+
shallow: true
|
|
2101
|
+
});
|
|
2102
|
+
var defaultShallowMapReactiveHandler = new MapReactiveHandler({
|
|
2103
|
+
readonly: false,
|
|
2104
|
+
shallow: true
|
|
2105
|
+
});
|
|
2106
|
+
var defaultShallowSetReactiveHandler = new SetReactiveHandler({
|
|
2107
|
+
readonly: false,
|
|
2108
|
+
shallow: true
|
|
2109
|
+
});
|
|
2110
|
+
function shallowReactive(raw) {
|
|
2111
|
+
if (isReactive(raw)) return raw;
|
|
2112
|
+
let proxy = rawToProxyCache.get(raw);
|
|
2113
|
+
if (proxy) return proxy;
|
|
2114
|
+
switch (getStringType(raw)) {
|
|
2115
|
+
case "[object Object]":
|
|
2116
|
+
proxy = new Proxy(raw, defaultShallowObjectReactiveHandler);
|
|
2117
|
+
break;
|
|
2118
|
+
case "[object Array]":
|
|
2119
|
+
proxy = new Proxy(raw, defaultShallowArrayReactiveHandler);
|
|
2120
|
+
break;
|
|
2121
|
+
case "[object Set]":
|
|
2122
|
+
case "[object WeakSet]":
|
|
2123
|
+
proxy = new Proxy(raw, defaultShallowSetReactiveHandler);
|
|
2124
|
+
break;
|
|
2125
|
+
case "[object Map]":
|
|
2126
|
+
case "[object WeakMap]":
|
|
2127
|
+
proxy = new Proxy(raw, defaultShallowMapReactiveHandler);
|
|
2128
|
+
break;
|
|
2129
|
+
default: return raw;
|
|
2130
|
+
}
|
|
2131
|
+
rawToProxyCache.set(raw, proxy);
|
|
2132
|
+
proxyToRawCache.set(proxy, raw);
|
|
2133
|
+
return proxy;
|
|
2134
|
+
}
|
|
2135
|
+
//#endregion
|
|
2136
|
+
//#region src/signals/signal.ts
|
|
2137
|
+
/**
|
|
2138
|
+
* 组件状态管理器
|
|
2139
|
+
* @param state 初始状态
|
|
2140
|
+
* @example
|
|
2141
|
+
* ```tsx
|
|
2142
|
+
* function App() {
|
|
2143
|
+
* // 初始化状态
|
|
2144
|
+
* const state = createSignal(1)
|
|
2145
|
+
*
|
|
2146
|
+
* return () => {
|
|
2147
|
+
* <div>
|
|
2148
|
+
* <div>当前值为:{state()}</div>
|
|
2149
|
+
* <div>
|
|
2150
|
+
* <button type="button" onClick={() => {
|
|
2151
|
+
* // 当点击时更新状态
|
|
2152
|
+
* state.set(state() + 1)
|
|
2153
|
+
* }
|
|
2154
|
+
* }>updateState</button>
|
|
2155
|
+
* </div>
|
|
2156
|
+
* </div>
|
|
2157
|
+
* }
|
|
2158
|
+
* }
|
|
2159
|
+
*/
|
|
2160
|
+
function createSignal(state) {
|
|
2161
|
+
const subscribers = /* @__PURE__ */ new Set();
|
|
2162
|
+
function signal() {
|
|
2163
|
+
const listener = getDepContext();
|
|
2164
|
+
if (listener && !subscribers.has(listener)) {
|
|
2165
|
+
listener.destroyCallbacks.push(() => {
|
|
2166
|
+
subscribers.delete(listener);
|
|
2167
|
+
});
|
|
2168
|
+
subscribers.add(listener);
|
|
2169
|
+
}
|
|
2170
|
+
return state;
|
|
2171
|
+
}
|
|
2172
|
+
signal.set = function(newValue) {
|
|
2173
|
+
if (newValue === state) return;
|
|
2174
|
+
state = newValue;
|
|
2175
|
+
Array.from(subscribers).forEach((listener) => listener.effect());
|
|
2176
|
+
};
|
|
2177
|
+
return signal;
|
|
2178
|
+
}
|
|
2179
|
+
//#endregion
|
|
2180
|
+
//#region src/signals/derived.ts
|
|
2181
|
+
/**
|
|
2182
|
+
* 使用派生值,Viewfly 会收集回调函数内同步执行时访问的 Signal,
|
|
2183
|
+
* 并在你获取 createDerived 函数返回的 Signal 的值时,自动计算最新的值。
|
|
2184
|
+
*
|
|
2185
|
+
* @param fn
|
|
2186
|
+
* @param isContinue 可选的停止函数,在每次值更新后调用,当返回值为 false 时,将不再监听依赖的变化
|
|
2187
|
+
*/
|
|
2188
|
+
function createDerived(fn, isContinue) {
|
|
2189
|
+
let isStop = false;
|
|
2190
|
+
function canListen(value) {
|
|
2191
|
+
if (isContinue) {
|
|
2192
|
+
if (isContinue(value) === false) {
|
|
2193
|
+
listener.destroy();
|
|
2194
|
+
return false;
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
return true;
|
|
2198
|
+
}
|
|
2199
|
+
const listener = new Dep(() => {
|
|
2200
|
+
if (isStop) return;
|
|
2201
|
+
isStop = true;
|
|
2202
|
+
listener.destroy();
|
|
2203
|
+
pushDepContext(listener);
|
|
2204
|
+
const value = fn();
|
|
2205
|
+
popDepContext();
|
|
2206
|
+
signal.set(value);
|
|
2207
|
+
canListen(value);
|
|
2208
|
+
isStop = false;
|
|
2209
|
+
});
|
|
2210
|
+
pushDepContext(listener);
|
|
2211
|
+
const value = fn();
|
|
2212
|
+
const signal = createSignal(value);
|
|
2213
|
+
popDepContext();
|
|
2214
|
+
isStop = false;
|
|
2215
|
+
if (canListen(value)) registryComponentDestroyCallback(() => listener.destroy());
|
|
2216
|
+
return signal;
|
|
2217
|
+
}
|
|
2218
|
+
//#endregion
|
|
2219
|
+
//#region src/signals/effect.ts
|
|
2220
|
+
function createEffect(deps, callback) {
|
|
2221
|
+
let prevFn;
|
|
2222
|
+
const isArray = Array.isArray(deps);
|
|
2223
|
+
const effect = new Dep(function() {
|
|
2224
|
+
if (prevFn) prevFn();
|
|
2225
|
+
const newValue = isArray ? deps.map((fn) => fn()) : deps();
|
|
2226
|
+
prevFn = callback(newValue, oldValue);
|
|
2227
|
+
oldValue = newValue;
|
|
2228
|
+
});
|
|
2229
|
+
pushDepContext(effect);
|
|
2230
|
+
let oldValue = isArray ? deps.map((fn) => fn()) : deps();
|
|
2231
|
+
popDepContext();
|
|
2232
|
+
let isUnWatch = false;
|
|
2233
|
+
function unWatch() {
|
|
2234
|
+
if (isUnWatch) return;
|
|
2235
|
+
isUnWatch = true;
|
|
2236
|
+
if (prevFn) prevFn();
|
|
2237
|
+
effect.destroy();
|
|
2238
|
+
}
|
|
2239
|
+
registryComponentDestroyCallback(unWatch);
|
|
2240
|
+
return unWatch;
|
|
2241
|
+
}
|
|
2242
|
+
//#endregion
|
|
2243
|
+
export { ArrayReactiveHandler, Component, Dep, DynamicRef, ForwardRef, Fragment, Inject, InjectFlags, Injectable, InjectionToken, Injector, JSXNodeFactory, MapReactiveHandler, NativeRenderer, NullInjector, ObjectReactiveHandler, Optional, Portal, Prop, ReflectiveInjector, RootComponent, Scope, Self, SetReactiveHandler, SkipSelf, StaticRef, THROW_IF_NOT_FOUND, TrackOpTypes, TriggerOpTypes, Type, applyMark, comparePropsWithCallbacks, computed, createContext, createContextProvider, createDerived, createDynamicRef, createEffect, createRef, createRenderer, createSignal, defaultArrayReactiveHandler, defaultMapReactiveHandler, defaultObjectReactiveHandler, defaultSetReactiveHandler, defaultShallowArrayReactiveHandler, defaultShallowMapReactiveHandler, defaultShallowObjectReactiveHandler, defaultShallowSetReactiveHandler, forwardRef, getCurrentInstance, getDepContext, getSetupContext, inject, internalWrite, isReactive, jsx, jsxs, makeError, normalizeProvider, onMounted, onUnmounted, onUpdated, popDepContext, proxyToRawCache, pushDepContext, rawToProxyCache, reactive, readonlyProxyHandler, registryComponentDestroyCallback, shallowReactive, toRaw, track, trigger, viewfly, watch, withAnnotation, withMark, withMemo };
|