@sigx/runtime-core 0.1.5 → 0.1.6
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/dist/app-types.d.ts +35 -15
- package/dist/app-types.d.ts.map +1 -1
- package/dist/app.d.ts +4 -8
- package/dist/app.d.ts.map +1 -1
- package/dist/component.d.ts +127 -38
- package/dist/component.d.ts.map +1 -1
- package/dist/compound.d.ts +34 -0
- package/dist/compound.d.ts.map +1 -0
- package/dist/di/factory.d.ts +3 -2
- package/dist/di/factory.d.ts.map +1 -1
- package/dist/di/injectable.d.ts +80 -6
- package/dist/di/injectable.d.ts.map +1 -1
- package/dist/hydration/index.d.ts +88 -0
- package/dist/hydration/index.d.ts.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +458 -690
- package/dist/index.js.map +1 -1
- package/dist/jsx-runtime.d.ts +3 -2
- package/dist/jsx-runtime.d.ts.map +1 -1
- package/dist/lazy.d.ts.map +1 -1
- package/dist/model.d.ts +68 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/platform.d.ts +9 -9
- package/dist/platform.d.ts.map +1 -1
- package/dist/renderer.d.ts +1 -3
- package/dist/renderer.d.ts.map +1 -1
- package/dist/utils/is-component.d.ts +30 -0
- package/dist/utils/is-component.d.ts.map +1 -0
- package/dist/utils/normalize.d.ts +4 -1
- package/dist/utils/normalize.d.ts.map +1 -1
- package/dist/utils/props-accessor.d.ts +6 -9
- package/dist/utils/props-accessor.d.ts.map +1 -1
- package/package.json +7 -6
- package/dist/sheet.d.ts +0 -51
- package/dist/sheet.d.ts.map +0 -1
- package/dist/stores/store.d.ts +0 -70
- package/dist/stores/store.d.ts.map +0 -1
- package/dist/styled.d.ts +0 -15
- package/dist/styled.d.ts.map +0 -1
- package/dist/utils/component-helpers.d.ts +0 -38
- package/dist/utils/component-helpers.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,107 +1,139 @@
|
|
|
1
|
-
import { detectAccess, effect,
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Set the platform-specific sync processor for intrinsic elements.
|
|
7
|
-
* Called by runtime-dom to handle checkbox/radio/select sync bindings.
|
|
8
|
-
*/
|
|
9
|
-
function setPlatformSyncProcessor(fn) {
|
|
10
|
-
platformSyncProcessor = fn;
|
|
1
|
+
import { detectAccess, effect, isComputed, signal, signal as signal$1, untrack } from "@sigx/reactivity";
|
|
2
|
+
var platformModelProcessor = null;
|
|
3
|
+
function setPlatformModelProcessor(fn) {
|
|
4
|
+
platformModelProcessor = fn;
|
|
11
5
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
*/
|
|
15
|
-
function getPlatformSyncProcessor() {
|
|
16
|
-
return platformSyncProcessor;
|
|
6
|
+
function getPlatformModelProcessor() {
|
|
7
|
+
return platformModelProcessor;
|
|
17
8
|
}
|
|
18
|
-
|
|
19
|
-
//#endregion
|
|
20
|
-
//#region src/plugins.ts
|
|
21
|
-
const plugins = [];
|
|
9
|
+
var plugins = [];
|
|
22
10
|
function registerComponentPlugin(plugin) {
|
|
23
11
|
plugins.push(plugin);
|
|
24
12
|
}
|
|
25
|
-
/**
|
|
26
|
-
* Get all registered plugins (internal use)
|
|
27
|
-
*/
|
|
28
13
|
function getComponentPlugins() {
|
|
29
14
|
return plugins;
|
|
30
15
|
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Register a function that will be called to extend every component context.
|
|
34
|
-
* Extensions are called in order of registration.
|
|
35
|
-
*
|
|
36
|
-
* @example
|
|
37
|
-
* ```ts
|
|
38
|
-
* // In @sigx/server-renderer/client
|
|
39
|
-
* registerContextExtension((ctx) => {
|
|
40
|
-
* ctx.ssr = { load: () => {} };
|
|
41
|
-
* });
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
16
|
+
var contextExtensions = [];
|
|
44
17
|
function registerContextExtension(extension) {
|
|
45
18
|
contextExtensions.push(extension);
|
|
46
19
|
}
|
|
47
|
-
/**
|
|
48
|
-
* Apply all registered context extensions to a context object.
|
|
49
|
-
* Called internally by the renderer when creating component contexts.
|
|
50
|
-
*/
|
|
51
20
|
function applyContextExtensions(ctx) {
|
|
52
21
|
for (const extension of contextExtensions) extension(ctx);
|
|
53
22
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
23
|
+
var currentComponentContext = null;
|
|
24
|
+
function getCurrentInstance() {
|
|
25
|
+
return currentComponentContext;
|
|
26
|
+
}
|
|
27
|
+
function setCurrentInstance(ctx) {
|
|
28
|
+
const prev = currentComponentContext;
|
|
29
|
+
currentComponentContext = ctx;
|
|
30
|
+
return prev;
|
|
31
|
+
}
|
|
32
|
+
function onMounted(fn) {
|
|
33
|
+
if (currentComponentContext) currentComponentContext.onMounted(fn);
|
|
34
|
+
else console.warn("onMounted called outside of component setup");
|
|
35
|
+
}
|
|
36
|
+
function onUnmounted(fn) {
|
|
37
|
+
if (currentComponentContext) currentComponentContext.onUnmounted(fn);
|
|
38
|
+
else console.warn("onUnmounted called outside of component setup");
|
|
39
|
+
}
|
|
40
|
+
function onCreated(fn) {
|
|
41
|
+
if (currentComponentContext) currentComponentContext.onCreated(fn);
|
|
42
|
+
else console.warn("onCreated called outside of component setup");
|
|
43
|
+
}
|
|
44
|
+
function onUpdated(fn) {
|
|
45
|
+
if (currentComponentContext) currentComponentContext.onUpdated(fn);
|
|
46
|
+
else console.warn("onUpdated called outside of component setup");
|
|
47
|
+
}
|
|
48
|
+
var componentRegistry = /* @__PURE__ */ new Map();
|
|
49
|
+
function getComponentMeta(factory) {
|
|
50
|
+
return componentRegistry.get(factory);
|
|
51
|
+
}
|
|
52
|
+
function createPropsProxy(target, onAccess) {
|
|
53
|
+
return new Proxy(target, { get(obj, prop) {
|
|
54
|
+
if (typeof prop === "string" && onAccess) onAccess(prop);
|
|
55
|
+
return obj[prop];
|
|
56
|
+
} });
|
|
57
|
+
}
|
|
58
|
+
function component(setup, options) {
|
|
59
|
+
const factory = function(props) {
|
|
60
|
+
return {
|
|
61
|
+
type: factory,
|
|
62
|
+
props: props || {},
|
|
63
|
+
key: props?.key || null,
|
|
64
|
+
children: [],
|
|
65
|
+
dom: null
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
factory.__setup = setup;
|
|
69
|
+
factory.__name = options?.name;
|
|
70
|
+
factory.__props = null;
|
|
71
|
+
factory.__events = null;
|
|
72
|
+
factory.__ref = null;
|
|
73
|
+
factory.__slots = null;
|
|
74
|
+
componentRegistry.set(factory, {
|
|
75
|
+
name: options?.name,
|
|
76
|
+
setup
|
|
77
|
+
});
|
|
78
|
+
getComponentPlugins().forEach((p) => p.onDefine?.(options?.name, factory, setup));
|
|
79
|
+
return factory;
|
|
80
|
+
}
|
|
81
|
+
var globalInstances = /* @__PURE__ */ new Map();
|
|
82
|
+
var appContextToken = Symbol("sigx:appContext");
|
|
83
|
+
function lookupProvided(token) {
|
|
84
|
+
const ctx = getCurrentInstance();
|
|
85
|
+
if (!ctx) return;
|
|
86
|
+
let current = ctx;
|
|
87
|
+
while (current) {
|
|
88
|
+
if (current.provides && current.provides.has(token)) return current.provides.get(token);
|
|
89
|
+
current = current.parent;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function provideAtComponent(token, value) {
|
|
93
|
+
const ctx = getCurrentInstance();
|
|
94
|
+
if (!ctx) throw new Error("defineProvide must be called inside a component setup function");
|
|
95
|
+
if (!ctx.provides) ctx.provides = /* @__PURE__ */ new Map();
|
|
96
|
+
ctx.provides.set(token, value);
|
|
97
|
+
}
|
|
98
|
+
function defineInjectable(factory) {
|
|
99
|
+
const token = Symbol();
|
|
100
|
+
const useFn = (() => {
|
|
101
|
+
const provided = lookupProvided(token);
|
|
102
|
+
if (provided !== void 0) return provided;
|
|
103
|
+
if (!globalInstances.has(token)) globalInstances.set(token, factory());
|
|
104
|
+
return globalInstances.get(token);
|
|
105
|
+
});
|
|
106
|
+
useFn._factory = factory;
|
|
107
|
+
useFn._token = token;
|
|
108
|
+
return useFn;
|
|
109
|
+
}
|
|
110
|
+
function defineProvide(useFn, factory) {
|
|
111
|
+
const actualFactory = factory ?? useFn._factory;
|
|
112
|
+
const token = useFn._token;
|
|
113
|
+
if (!actualFactory || !token) throw new Error("defineProvide must be called with a function created by defineInjectable");
|
|
114
|
+
const instance = actualFactory();
|
|
115
|
+
provideAtComponent(token, instance);
|
|
116
|
+
return instance;
|
|
117
|
+
}
|
|
118
|
+
function useAppContext() {
|
|
119
|
+
return lookupProvided(appContextToken) ?? null;
|
|
120
|
+
}
|
|
121
|
+
function getAppContextToken() {
|
|
122
|
+
return appContextToken;
|
|
123
|
+
}
|
|
124
|
+
function provideAppContext(ctx, appContext) {
|
|
125
|
+
if (!ctx.provides) ctx.provides = /* @__PURE__ */ new Map();
|
|
126
|
+
ctx.provides.set(appContextToken, appContext);
|
|
127
|
+
if (appContext.provides) for (const [token, value] of appContext.provides) ctx.provides.set(token, value);
|
|
128
|
+
}
|
|
129
|
+
var isDev = typeof process !== "undefined" && process.env.NODE_ENV !== "production" || true;
|
|
130
|
+
var defaultMountFn = null;
|
|
74
131
|
function setDefaultMount(mountFn) {
|
|
75
132
|
defaultMountFn = mountFn;
|
|
76
133
|
}
|
|
77
|
-
/**
|
|
78
|
-
* Get the current default mount function.
|
|
79
|
-
* @internal
|
|
80
|
-
*/
|
|
81
134
|
function getDefaultMount() {
|
|
82
135
|
return defaultMountFn;
|
|
83
136
|
}
|
|
84
|
-
/**
|
|
85
|
-
* Create an application instance.
|
|
86
|
-
*
|
|
87
|
-
* @example
|
|
88
|
-
* ```tsx
|
|
89
|
-
* import { defineApp, defineInjectable } from '@sigx/runtime-core';
|
|
90
|
-
* import { render } from '@sigx/runtime-dom';
|
|
91
|
-
*
|
|
92
|
-
* // Define an injectable service
|
|
93
|
-
* const useApiConfig = defineInjectable(() => ({ baseUrl: 'https://api.example.com' }));
|
|
94
|
-
*
|
|
95
|
-
* const app = defineApp(<App />);
|
|
96
|
-
*
|
|
97
|
-
* app.use(myPlugin, { option: 'value' });
|
|
98
|
-
*
|
|
99
|
-
* // Provide using the injectable token (works with inject())
|
|
100
|
-
* app.provide(useApiConfig, { baseUrl: 'https://custom.api.com' });
|
|
101
|
-
*
|
|
102
|
-
* app.mount(document.getElementById('app')!, render);
|
|
103
|
-
* ```
|
|
104
|
-
*/
|
|
105
137
|
function defineApp(rootComponent) {
|
|
106
138
|
const installedPlugins = /* @__PURE__ */ new Set();
|
|
107
139
|
const context = {
|
|
@@ -126,11 +158,13 @@ function defineApp(rootComponent) {
|
|
|
126
158
|
else if (isDev) console.warn("Invalid plugin: must be a function or have an install() method.");
|
|
127
159
|
return app;
|
|
128
160
|
},
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
161
|
+
defineProvide(useFn, factory) {
|
|
162
|
+
const actualFactory = factory ?? useFn._factory;
|
|
163
|
+
const token = useFn._token;
|
|
164
|
+
if (!actualFactory || !token) throw new Error("defineProvide must be called with a function created by defineInjectable");
|
|
165
|
+
const instance = actualFactory();
|
|
166
|
+
context.provides.set(token, instance);
|
|
167
|
+
return instance;
|
|
134
168
|
},
|
|
135
169
|
hook(hooks) {
|
|
136
170
|
context.hooks.push(hooks);
|
|
@@ -167,15 +201,16 @@ function defineApp(rootComponent) {
|
|
|
167
201
|
},
|
|
168
202
|
get _container() {
|
|
169
203
|
return container;
|
|
204
|
+
},
|
|
205
|
+
get _rootComponent() {
|
|
206
|
+
return rootComponent;
|
|
170
207
|
}
|
|
171
208
|
};
|
|
172
209
|
context.app = app;
|
|
210
|
+
const appContextToken = getAppContextToken();
|
|
211
|
+
context.provides.set(appContextToken, context);
|
|
173
212
|
return app;
|
|
174
213
|
}
|
|
175
|
-
/**
|
|
176
|
-
* Notify all app hooks that a component was created.
|
|
177
|
-
* Called by the renderer after setup() returns.
|
|
178
|
-
*/
|
|
179
214
|
function notifyComponentCreated(context, instance) {
|
|
180
215
|
if (!context) return;
|
|
181
216
|
for (const hooks of context.hooks) try {
|
|
@@ -184,10 +219,6 @@ function notifyComponentCreated(context, instance) {
|
|
|
184
219
|
handleHookError(context, err, instance, "onComponentCreated");
|
|
185
220
|
}
|
|
186
221
|
}
|
|
187
|
-
/**
|
|
188
|
-
* Notify all app hooks that a component was mounted.
|
|
189
|
-
* Called by the renderer after mount hooks run.
|
|
190
|
-
*/
|
|
191
222
|
function notifyComponentMounted(context, instance) {
|
|
192
223
|
if (!context) return;
|
|
193
224
|
for (const hooks of context.hooks) try {
|
|
@@ -196,10 +227,6 @@ function notifyComponentMounted(context, instance) {
|
|
|
196
227
|
handleHookError(context, err, instance, "onComponentMounted");
|
|
197
228
|
}
|
|
198
229
|
}
|
|
199
|
-
/**
|
|
200
|
-
* Notify all app hooks that a component was unmounted.
|
|
201
|
-
* Called by the renderer before cleanup.
|
|
202
|
-
*/
|
|
203
230
|
function notifyComponentUnmounted(context, instance) {
|
|
204
231
|
if (!context) return;
|
|
205
232
|
for (const hooks of context.hooks) try {
|
|
@@ -208,10 +235,6 @@ function notifyComponentUnmounted(context, instance) {
|
|
|
208
235
|
handleHookError(context, err, instance, "onComponentUnmounted");
|
|
209
236
|
}
|
|
210
237
|
}
|
|
211
|
-
/**
|
|
212
|
-
* Notify all app hooks that a component updated.
|
|
213
|
-
* Called by the renderer after re-render.
|
|
214
|
-
*/
|
|
215
238
|
function notifyComponentUpdated(context, instance) {
|
|
216
239
|
if (!context) return;
|
|
217
240
|
for (const hooks of context.hooks) try {
|
|
@@ -220,10 +243,6 @@ function notifyComponentUpdated(context, instance) {
|
|
|
220
243
|
handleHookError(context, err, instance, "onComponentUpdated");
|
|
221
244
|
}
|
|
222
245
|
}
|
|
223
|
-
/**
|
|
224
|
-
* Handle an error in a component. Returns true if the error was handled.
|
|
225
|
-
* Called by the renderer when an error occurs in setup or render.
|
|
226
|
-
*/
|
|
227
246
|
function handleComponentError(context, err, instance, info) {
|
|
228
247
|
if (!context) return false;
|
|
229
248
|
for (const hooks of context.hooks) try {
|
|
@@ -238,104 +257,53 @@ function handleComponentError(context, err, instance, info) {
|
|
|
238
257
|
}
|
|
239
258
|
return false;
|
|
240
259
|
}
|
|
241
|
-
/**
|
|
242
|
-
* Handle errors that occur in hooks themselves
|
|
243
|
-
*/
|
|
244
260
|
function handleHookError(context, err, instance, hookName) {
|
|
245
261
|
console.error(`Error in ${hookName} hook:`, err);
|
|
246
262
|
if (context.config.errorHandler) try {
|
|
247
263
|
context.config.errorHandler(err, instance, `plugin hook: ${hookName}`);
|
|
248
264
|
} catch {}
|
|
249
265
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
//#region src/component.ts
|
|
253
|
-
let currentComponentContext = null;
|
|
254
|
-
function getCurrentInstance() {
|
|
255
|
-
return currentComponentContext;
|
|
256
|
-
}
|
|
257
|
-
function setCurrentInstance(ctx) {
|
|
258
|
-
const prev = currentComponentContext;
|
|
259
|
-
currentComponentContext = ctx;
|
|
260
|
-
return prev;
|
|
266
|
+
function compound(main, sub) {
|
|
267
|
+
return Object.assign(main, sub);
|
|
261
268
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
269
|
+
var MODEL_SYMBOL = Symbol.for("sigx.model");
|
|
270
|
+
function createModel(tuple, updateHandler) {
|
|
271
|
+
const [obj, key] = tuple;
|
|
272
|
+
return {
|
|
273
|
+
get value() {
|
|
274
|
+
return obj[key];
|
|
275
|
+
},
|
|
276
|
+
set value(v) {
|
|
277
|
+
updateHandler(v);
|
|
278
|
+
},
|
|
279
|
+
get binding() {
|
|
280
|
+
return [
|
|
281
|
+
obj,
|
|
282
|
+
key,
|
|
283
|
+
updateHandler
|
|
284
|
+
];
|
|
285
|
+
},
|
|
286
|
+
[MODEL_SYMBOL]: true
|
|
287
|
+
};
|
|
265
288
|
}
|
|
266
|
-
function
|
|
267
|
-
|
|
268
|
-
|
|
289
|
+
function createModelFromBinding(binding) {
|
|
290
|
+
const [obj, key, handler] = binding;
|
|
291
|
+
return createModel([obj, key], handler);
|
|
269
292
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
* Get component metadata (for DevTools)
|
|
273
|
-
*/
|
|
274
|
-
function getComponentMeta(factory) {
|
|
275
|
-
return componentRegistry.get(factory);
|
|
293
|
+
function isModel(value) {
|
|
294
|
+
return value !== null && typeof value === "object" && MODEL_SYMBOL in value && value[MODEL_SYMBOL] === true;
|
|
276
295
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
*/
|
|
280
|
-
function createPropsProxy(target, onAccess) {
|
|
281
|
-
return new Proxy(target, { get(obj, prop) {
|
|
282
|
-
if (typeof prop === "string" && onAccess) onAccess(prop);
|
|
283
|
-
return obj[prop];
|
|
284
|
-
} });
|
|
296
|
+
function getModelSymbol() {
|
|
297
|
+
return MODEL_SYMBOL;
|
|
285
298
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
*
|
|
289
|
-
* @param setup - Setup function that receives context and returns a render function
|
|
290
|
-
* @param options - Optional configuration (e.g., name for DevTools)
|
|
291
|
-
*
|
|
292
|
-
* @example
|
|
293
|
-
* ```tsx
|
|
294
|
-
* type CardProps = DefineProp<"title", string> & DefineSlot<"header">;
|
|
295
|
-
*
|
|
296
|
-
* export const Card = defineComponent<CardProps>((ctx) => {
|
|
297
|
-
* const { title } = ctx.props;
|
|
298
|
-
* const { slots } = ctx;
|
|
299
|
-
*
|
|
300
|
-
* return () => (
|
|
301
|
-
* <div class="card">
|
|
302
|
-
* {slots.header?.() ?? <h2>{title}</h2>}
|
|
303
|
-
* {slots.default()}
|
|
304
|
-
* </div>
|
|
305
|
-
* );
|
|
306
|
-
* });
|
|
307
|
-
* ```
|
|
308
|
-
*/
|
|
309
|
-
function defineComponent(setup, options) {
|
|
310
|
-
const factory = function(props) {
|
|
311
|
-
return {
|
|
312
|
-
type: factory,
|
|
313
|
-
props: props || {},
|
|
314
|
-
key: props?.key || null,
|
|
315
|
-
children: [],
|
|
316
|
-
dom: null
|
|
317
|
-
};
|
|
318
|
-
};
|
|
319
|
-
factory.__setup = setup;
|
|
320
|
-
factory.__name = options?.name;
|
|
321
|
-
factory.__props = null;
|
|
322
|
-
factory.__events = null;
|
|
323
|
-
factory.__ref = null;
|
|
324
|
-
factory.__slots = null;
|
|
325
|
-
componentRegistry.set(factory, {
|
|
326
|
-
name: options?.name,
|
|
327
|
-
setup
|
|
328
|
-
});
|
|
329
|
-
getComponentPlugins().forEach((p) => p.onDefine?.(options?.name, factory, setup));
|
|
330
|
-
return factory;
|
|
299
|
+
function isComponent(type) {
|
|
300
|
+
return typeof type === "function" && "__setup" in type;
|
|
331
301
|
}
|
|
332
|
-
|
|
333
|
-
//#endregion
|
|
334
|
-
//#region src/jsx-runtime.ts
|
|
335
302
|
const Fragment = Symbol.for("sigx.Fragment");
|
|
336
303
|
const Text = Symbol.for("sigx.Text");
|
|
337
304
|
function normalizeChildren(children) {
|
|
338
305
|
if (children == null || children === false || children === true) return [];
|
|
306
|
+
if (isComputed(children)) return normalizeChildren(children.value);
|
|
339
307
|
if (Array.isArray(children)) return children.flatMap((c) => normalizeChildren(c));
|
|
340
308
|
if (typeof children === "string" || typeof children === "number") return [{
|
|
341
309
|
type: Text,
|
|
@@ -348,64 +316,92 @@ function normalizeChildren(children) {
|
|
|
348
316
|
if (children.type) return [children];
|
|
349
317
|
return [];
|
|
350
318
|
}
|
|
351
|
-
/**
|
|
352
|
-
* Check if a type is a sigx component (has __setup)
|
|
353
|
-
*/
|
|
354
|
-
function isComponent$1(type) {
|
|
355
|
-
return typeof type === "function" && "__setup" in type;
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* Create a JSX element - this is the core function called by TSX transpilation
|
|
359
|
-
*/
|
|
360
319
|
function jsx(type, props, key) {
|
|
361
320
|
const processedProps = { ...props || {} };
|
|
321
|
+
const models = {};
|
|
322
|
+
const isComponentType = isComponent(type);
|
|
362
323
|
if (props) {
|
|
363
|
-
for (const propKey in props) if (propKey === "
|
|
364
|
-
let
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
324
|
+
for (const propKey in props) if (propKey === "model") {
|
|
325
|
+
let modelBinding = props[propKey];
|
|
326
|
+
let tuple = null;
|
|
327
|
+
let updateHandler = null;
|
|
328
|
+
if (isModel(modelBinding)) {
|
|
329
|
+
const [obj, key, handler] = modelBinding.binding;
|
|
330
|
+
tuple = [obj, key];
|
|
331
|
+
updateHandler = handler;
|
|
332
|
+
} else if (typeof modelBinding === "function") {
|
|
333
|
+
const detected = detectAccess(modelBinding);
|
|
334
|
+
if (detected && typeof detected[1] === "string") tuple = detected;
|
|
335
|
+
} else if (Array.isArray(modelBinding) && modelBinding.length === 2 && typeof modelBinding[1] === "string") tuple = modelBinding;
|
|
336
|
+
if (tuple) {
|
|
337
|
+
const [stateObj, stateKey] = tuple;
|
|
371
338
|
let handled = false;
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
stateObj[key$1] = v;
|
|
339
|
+
if (!updateHandler) {
|
|
340
|
+
const existingHandler = processedProps["onUpdate:modelValue"];
|
|
341
|
+
updateHandler = (v) => {
|
|
342
|
+
const customHandler = stateObj[`onUpdate:${stateKey}`];
|
|
343
|
+
if (typeof customHandler === "function") customHandler(v);
|
|
344
|
+
else stateObj[stateKey] = v;
|
|
379
345
|
if (existingHandler) existingHandler(v);
|
|
380
346
|
};
|
|
381
347
|
}
|
|
382
|
-
|
|
348
|
+
const platformProcessor = getPlatformModelProcessor();
|
|
349
|
+
if (typeof type === "string" && platformProcessor) handled = platformProcessor(type, processedProps, tuple, props);
|
|
350
|
+
if (isComponentType) {
|
|
351
|
+
models.model = createModel(tuple, updateHandler);
|
|
352
|
+
processedProps["onUpdate:modelValue"] = updateHandler;
|
|
353
|
+
} else if (!handled) {
|
|
354
|
+
processedProps.modelValue = stateObj[stateKey];
|
|
355
|
+
processedProps["onUpdate:modelValue"] = updateHandler;
|
|
356
|
+
}
|
|
357
|
+
delete processedProps.model;
|
|
383
358
|
}
|
|
384
|
-
} else if (propKey.startsWith("
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
359
|
+
} else if (propKey.startsWith("model:")) {
|
|
360
|
+
let modelBinding = props[propKey];
|
|
361
|
+
const name = propKey.slice(6);
|
|
362
|
+
let tuple = null;
|
|
363
|
+
let updateHandler = null;
|
|
364
|
+
if (isModel(modelBinding)) {
|
|
365
|
+
const [obj, key, handler] = modelBinding.binding;
|
|
366
|
+
tuple = [obj, key];
|
|
367
|
+
updateHandler = handler;
|
|
368
|
+
} else if (typeof modelBinding === "function") {
|
|
369
|
+
const detected = detectAccess(modelBinding);
|
|
370
|
+
if (detected && typeof detected[1] === "string") tuple = detected;
|
|
371
|
+
} else if (Array.isArray(modelBinding) && modelBinding.length === 2 && typeof modelBinding[1] === "string") tuple = modelBinding;
|
|
372
|
+
if (tuple) {
|
|
373
|
+
const [stateObj, stateKey] = tuple;
|
|
390
374
|
const eventName = `onUpdate:${name}`;
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
375
|
+
if (!updateHandler) {
|
|
376
|
+
const existingHandler = processedProps[eventName];
|
|
377
|
+
updateHandler = (v) => {
|
|
378
|
+
const customHandler = stateObj[`onUpdate:${stateKey}`];
|
|
379
|
+
if (typeof customHandler === "function") customHandler(v);
|
|
380
|
+
else stateObj[stateKey] = v;
|
|
381
|
+
if (existingHandler) existingHandler(v);
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
if (isComponentType) {
|
|
385
|
+
models[name] = createModel(tuple, updateHandler);
|
|
386
|
+
processedProps[eventName] = updateHandler;
|
|
387
|
+
} else {
|
|
388
|
+
processedProps[name] = stateObj[stateKey];
|
|
389
|
+
processedProps[eventName] = updateHandler;
|
|
390
|
+
}
|
|
396
391
|
delete processedProps[propKey];
|
|
397
392
|
}
|
|
398
393
|
}
|
|
399
394
|
}
|
|
400
|
-
if (
|
|
401
|
-
|
|
395
|
+
if (Object.keys(models).length > 0) processedProps.$models = models;
|
|
396
|
+
if (isComponent(type)) {
|
|
397
|
+
const { children, ...rest } = processedProps;
|
|
402
398
|
return {
|
|
403
399
|
type,
|
|
404
400
|
props: {
|
|
405
|
-
...rest
|
|
406
|
-
children
|
|
401
|
+
...rest,
|
|
402
|
+
children
|
|
407
403
|
},
|
|
408
|
-
key: key || rest
|
|
404
|
+
key: key || rest.key || null,
|
|
409
405
|
children: [],
|
|
410
406
|
dom: null
|
|
411
407
|
};
|
|
@@ -420,27 +416,11 @@ function jsx(type, props, key) {
|
|
|
420
416
|
dom: null
|
|
421
417
|
};
|
|
422
418
|
}
|
|
423
|
-
/**
|
|
424
|
-
* JSX Factory for fragments
|
|
425
|
-
*/
|
|
426
419
|
function jsxs(type, props, key) {
|
|
427
420
|
return jsx(type, props, key);
|
|
428
421
|
}
|
|
429
422
|
const jsxDEV = jsx;
|
|
430
|
-
|
|
431
|
-
//#endregion
|
|
432
|
-
//#region src/lazy.tsx
|
|
433
|
-
/**
|
|
434
|
-
* Lazy loading utilities for sigx components.
|
|
435
|
-
*
|
|
436
|
-
* Provides runtime-only lazy loading with no build dependencies.
|
|
437
|
-
* Works with any bundler that supports dynamic import().
|
|
438
|
-
*/
|
|
439
|
-
let currentSuspenseBoundary = null;
|
|
440
|
-
/**
|
|
441
|
-
* Register a promise with the current Suspense boundary
|
|
442
|
-
* @internal
|
|
443
|
-
*/
|
|
423
|
+
var currentSuspenseBoundary = null;
|
|
444
424
|
function registerPendingPromise(promise) {
|
|
445
425
|
const boundary = currentSuspenseBoundary;
|
|
446
426
|
if (boundary) {
|
|
@@ -453,39 +433,12 @@ function registerPendingPromise(promise) {
|
|
|
453
433
|
}
|
|
454
434
|
return false;
|
|
455
435
|
}
|
|
456
|
-
/**
|
|
457
|
-
* Create a lazy-loaded component wrapper.
|
|
458
|
-
*
|
|
459
|
-
* The component will be loaded on first render. Use with `<Suspense>` to show
|
|
460
|
-
* a fallback while loading.
|
|
461
|
-
*
|
|
462
|
-
* @param loader - Function that returns a Promise resolving to the component
|
|
463
|
-
* @returns A component factory that loads the real component on demand
|
|
464
|
-
*
|
|
465
|
-
* @example
|
|
466
|
-
* ```tsx
|
|
467
|
-
* import { lazy, Suspense } from 'sigx';
|
|
468
|
-
*
|
|
469
|
-
* // Component will be in a separate chunk
|
|
470
|
-
* const HeavyChart = lazy(() => import('./components/HeavyChart'));
|
|
471
|
-
*
|
|
472
|
-
* // Usage
|
|
473
|
-
* <Suspense fallback={<Spinner />}>
|
|
474
|
-
* <HeavyChart data={chartData} />
|
|
475
|
-
* </Suspense>
|
|
476
|
-
*
|
|
477
|
-
* // Preload on hover
|
|
478
|
-
* <button onMouseEnter={() => HeavyChart.preload()}>
|
|
479
|
-
* Show Chart
|
|
480
|
-
* </button>
|
|
481
|
-
* ```
|
|
482
|
-
*/
|
|
483
436
|
function lazy(loader) {
|
|
484
437
|
let Component = null;
|
|
485
438
|
let promise = null;
|
|
486
439
|
let error = null;
|
|
487
440
|
let state = "pending";
|
|
488
|
-
const LazyWrapper =
|
|
441
|
+
const LazyWrapper = component((ctx) => {
|
|
489
442
|
const loadState = ctx.signal({
|
|
490
443
|
state,
|
|
491
444
|
tick: 0
|
|
@@ -534,30 +487,7 @@ function lazy(loader) {
|
|
|
534
487
|
};
|
|
535
488
|
return LazyWrapper;
|
|
536
489
|
}
|
|
537
|
-
|
|
538
|
-
* Suspense boundary component for handling async loading states.
|
|
539
|
-
*
|
|
540
|
-
* Wraps lazy-loaded components and shows a fallback while they load.
|
|
541
|
-
*
|
|
542
|
-
* @example
|
|
543
|
-
* ```tsx
|
|
544
|
-
* import { lazy, Suspense } from 'sigx';
|
|
545
|
-
*
|
|
546
|
-
* const LazyDashboard = lazy(() => import('./Dashboard'));
|
|
547
|
-
*
|
|
548
|
-
* // Basic usage
|
|
549
|
-
* <Suspense fallback={<div>Loading...</div>}>
|
|
550
|
-
* <LazyDashboard />
|
|
551
|
-
* </Suspense>
|
|
552
|
-
*
|
|
553
|
-
* // With spinner component
|
|
554
|
-
* <Suspense fallback={<Spinner size="large" />}>
|
|
555
|
-
* <LazyDashboard />
|
|
556
|
-
* <LazyCharts />
|
|
557
|
-
* </Suspense>
|
|
558
|
-
* ```
|
|
559
|
-
*/
|
|
560
|
-
const Suspense = defineComponent((ctx) => {
|
|
490
|
+
const Suspense = component((ctx) => {
|
|
561
491
|
const { props, slots } = ctx;
|
|
562
492
|
const state = ctx.signal({
|
|
563
493
|
isReady: false,
|
|
@@ -570,7 +500,7 @@ const Suspense = defineComponent((ctx) => {
|
|
|
570
500
|
if (boundary.pending.size === 0) state.isReady = true;
|
|
571
501
|
}
|
|
572
502
|
};
|
|
573
|
-
ctx.
|
|
503
|
+
ctx.onMounted(() => {
|
|
574
504
|
if (boundary.pending.size === 0) state.isReady = true;
|
|
575
505
|
});
|
|
576
506
|
return () => {
|
|
@@ -605,15 +535,9 @@ const Suspense = defineComponent((ctx) => {
|
|
|
605
535
|
}
|
|
606
536
|
};
|
|
607
537
|
}, { name: "Suspense" });
|
|
608
|
-
/**
|
|
609
|
-
* Check if a component is a lazy-loaded component
|
|
610
|
-
*/
|
|
611
538
|
function isLazyComponent(component) {
|
|
612
539
|
return component && component.__lazy === true;
|
|
613
540
|
}
|
|
614
|
-
|
|
615
|
-
//#endregion
|
|
616
|
-
//#region src/utils/index.ts
|
|
617
541
|
var Utils = class {
|
|
618
542
|
static isPromise(value) {
|
|
619
543
|
return !!value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
|
|
@@ -625,92 +549,29 @@ function guid$1() {
|
|
|
625
549
|
return (c == "x" ? r : r & 3 | 8).toString(16);
|
|
626
550
|
});
|
|
627
551
|
}
|
|
628
|
-
|
|
629
|
-
//#endregion
|
|
630
|
-
//#region src/utils/props-accessor.ts
|
|
631
|
-
/**
|
|
632
|
-
* Creates a props accessor that can be called with defaults or accessed directly.
|
|
633
|
-
* After calling with defaults, direct property access uses those defaults.
|
|
634
|
-
*
|
|
635
|
-
* @example
|
|
636
|
-
* ```ts
|
|
637
|
-
* // In component setup:
|
|
638
|
-
* const props = createPropsAccessor(reactiveProps);
|
|
639
|
-
*
|
|
640
|
-
* // Set defaults
|
|
641
|
-
* props({ count: 0, label: 'Default' });
|
|
642
|
-
*
|
|
643
|
-
* // Access props (falls back to defaults if not provided)
|
|
644
|
-
* const count = props.count;
|
|
645
|
-
* ```
|
|
646
|
-
*/
|
|
647
552
|
function createPropsAccessor(reactiveProps) {
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
get(_, key) {
|
|
553
|
+
return new Proxy(reactiveProps, {
|
|
554
|
+
get(target, key) {
|
|
651
555
|
if (typeof key === "symbol") return void 0;
|
|
652
|
-
|
|
653
|
-
return value != null ? value : defaults[key];
|
|
556
|
+
return target[key];
|
|
654
557
|
},
|
|
655
|
-
|
|
656
|
-
if (args[0] && typeof args[0] === "object") defaults = {
|
|
657
|
-
...defaults,
|
|
658
|
-
...args[0]
|
|
659
|
-
};
|
|
660
|
-
return proxy;
|
|
661
|
-
},
|
|
662
|
-
has(_, key) {
|
|
558
|
+
has(target, key) {
|
|
663
559
|
if (typeof key === "symbol") return false;
|
|
664
|
-
return key in
|
|
560
|
+
return key in target;
|
|
665
561
|
},
|
|
666
|
-
ownKeys() {
|
|
667
|
-
return
|
|
562
|
+
ownKeys(target) {
|
|
563
|
+
return Object.keys(target);
|
|
668
564
|
},
|
|
669
|
-
getOwnPropertyDescriptor(
|
|
565
|
+
getOwnPropertyDescriptor(target, key) {
|
|
670
566
|
if (typeof key === "symbol") return void 0;
|
|
671
|
-
if (key in
|
|
567
|
+
if (key in target) return {
|
|
672
568
|
enumerable: true,
|
|
673
569
|
configurable: true,
|
|
674
570
|
writable: false
|
|
675
571
|
};
|
|
676
572
|
}
|
|
677
573
|
});
|
|
678
|
-
return proxy;
|
|
679
574
|
}
|
|
680
|
-
|
|
681
|
-
//#endregion
|
|
682
|
-
//#region src/utils/slots.ts
|
|
683
|
-
/**
|
|
684
|
-
* Slots system for component children.
|
|
685
|
-
* Supports default and named slots with reactivity.
|
|
686
|
-
*/
|
|
687
|
-
/**
|
|
688
|
-
* Create slots object from children and slots prop.
|
|
689
|
-
* Uses a version signal to trigger re-renders when children change.
|
|
690
|
-
*
|
|
691
|
-
* Supports named slots via:
|
|
692
|
-
* - `slots` prop object (e.g., `slots={{ header: () => <div>...</div> }}`)
|
|
693
|
-
* - `slot` prop on children (e.g., `<div slot="header">...</div>`)
|
|
694
|
-
*
|
|
695
|
-
* @example
|
|
696
|
-
* ```tsx
|
|
697
|
-
* // Parent component
|
|
698
|
-
* <Card slots={{ header: () => <h1>Title</h1> }}>
|
|
699
|
-
* <p>Default content</p>
|
|
700
|
-
* <span slot="footer">Footer text</span>
|
|
701
|
-
* </Card>
|
|
702
|
-
*
|
|
703
|
-
* // Card component setup
|
|
704
|
-
* const slots = createSlots(children, slotsFromProps);
|
|
705
|
-
* return () => (
|
|
706
|
-
* <div>
|
|
707
|
-
* {slots.header()}
|
|
708
|
-
* {slots.default()}
|
|
709
|
-
* {slots.footer()}
|
|
710
|
-
* </div>
|
|
711
|
-
* );
|
|
712
|
-
* ```
|
|
713
|
-
*/
|
|
714
575
|
function createSlots(children, slotsFromProps) {
|
|
715
576
|
const versionSignal = signal$1({ v: 0 });
|
|
716
577
|
function extractNamedSlotsFromChildren(c) {
|
|
@@ -757,37 +618,6 @@ function createSlots(children, slotsFromProps) {
|
|
|
757
618
|
};
|
|
758
619
|
} });
|
|
759
620
|
}
|
|
760
|
-
|
|
761
|
-
//#endregion
|
|
762
|
-
//#region src/utils/normalize.ts
|
|
763
|
-
/**
|
|
764
|
-
* VNode normalization utilities.
|
|
765
|
-
* Converts render results into proper VNode structures.
|
|
766
|
-
*/
|
|
767
|
-
/**
|
|
768
|
-
* Normalize render result to a VNode (wrapping arrays in Fragment).
|
|
769
|
-
* Handles null, undefined, false, true by returning an empty Text node.
|
|
770
|
-
*
|
|
771
|
-
* This is used to normalize the return value of component render functions
|
|
772
|
-
* into a consistent VNode structure for the renderer to process.
|
|
773
|
-
*
|
|
774
|
-
* @example
|
|
775
|
-
* ```ts
|
|
776
|
-
* // Conditional rendering returns null/false
|
|
777
|
-
* normalizeSubTree(null) // → empty Text node
|
|
778
|
-
* normalizeSubTree(false) // → empty Text node
|
|
779
|
-
*
|
|
780
|
-
* // Arrays become Fragments
|
|
781
|
-
* normalizeSubTree([<A/>, <B/>]) // → Fragment with children
|
|
782
|
-
*
|
|
783
|
-
* // Primitives become Text nodes
|
|
784
|
-
* normalizeSubTree("hello") // → Text node
|
|
785
|
-
* normalizeSubTree(42) // → Text node
|
|
786
|
-
*
|
|
787
|
-
* // VNodes pass through
|
|
788
|
-
* normalizeSubTree(<div/>) // → same VNode
|
|
789
|
-
* ```
|
|
790
|
-
*/
|
|
791
621
|
function normalizeSubTree(result) {
|
|
792
622
|
if (result == null || result === false || result === true) return {
|
|
793
623
|
type: Text,
|
|
@@ -797,6 +627,7 @@ function normalizeSubTree(result) {
|
|
|
797
627
|
dom: null,
|
|
798
628
|
text: ""
|
|
799
629
|
};
|
|
630
|
+
if (isComputed(result)) return normalizeSubTree(result.value);
|
|
800
631
|
if (Array.isArray(result)) return {
|
|
801
632
|
type: Fragment,
|
|
802
633
|
props: {},
|
|
@@ -814,22 +645,16 @@ function normalizeSubTree(result) {
|
|
|
814
645
|
};
|
|
815
646
|
return result;
|
|
816
647
|
}
|
|
817
|
-
|
|
818
|
-
//#endregion
|
|
819
|
-
//#region src/models/index.ts
|
|
820
648
|
const guid = guid$1;
|
|
821
|
-
let InstanceLifetimes = /* @__PURE__ */ function(InstanceLifetimes
|
|
822
|
-
InstanceLifetimes
|
|
823
|
-
InstanceLifetimes
|
|
824
|
-
InstanceLifetimes
|
|
825
|
-
return InstanceLifetimes
|
|
649
|
+
let InstanceLifetimes = /* @__PURE__ */ function(InstanceLifetimes) {
|
|
650
|
+
InstanceLifetimes[InstanceLifetimes["Transient"] = 0] = "Transient";
|
|
651
|
+
InstanceLifetimes[InstanceLifetimes["Scoped"] = 1] = "Scoped";
|
|
652
|
+
InstanceLifetimes[InstanceLifetimes["Singleton"] = 2] = "Singleton";
|
|
653
|
+
return InstanceLifetimes;
|
|
826
654
|
}({});
|
|
827
655
|
function valueOf(obj) {
|
|
828
656
|
return obj;
|
|
829
657
|
}
|
|
830
|
-
|
|
831
|
-
//#endregion
|
|
832
|
-
//#region src/messaging/index.ts
|
|
833
658
|
function createTopic(options) {
|
|
834
659
|
let subscribers = [];
|
|
835
660
|
const publish = (data) => {
|
|
@@ -842,7 +667,7 @@ function createTopic(options) {
|
|
|
842
667
|
if (idx > -1) subscribers.splice(idx, 1);
|
|
843
668
|
};
|
|
844
669
|
try {
|
|
845
|
-
|
|
670
|
+
onUnmounted(unsubscribe);
|
|
846
671
|
} catch (e) {}
|
|
847
672
|
return { unsubscribe };
|
|
848
673
|
};
|
|
@@ -858,72 +683,10 @@ function createTopic(options) {
|
|
|
858
683
|
function toSubscriber(topic) {
|
|
859
684
|
return { subscribe: (handler) => topic.subscribe(handler) };
|
|
860
685
|
}
|
|
861
|
-
|
|
862
|
-
//#endregion
|
|
863
|
-
//#region src/di/injectable.ts
|
|
864
|
-
function inject(token) {
|
|
865
|
-
const ctx = getCurrentInstance();
|
|
866
|
-
if (!ctx) return void 0;
|
|
867
|
-
let current = ctx;
|
|
868
|
-
while (current) {
|
|
869
|
-
if (current.provides && current.provides.has(token)) return current.provides.get(token);
|
|
870
|
-
current = current.parent;
|
|
871
|
-
}
|
|
872
|
-
const appContext = getAppContext(ctx);
|
|
873
|
-
if (appContext && appContext.provides.has(token)) return appContext.provides.get(token);
|
|
874
|
-
}
|
|
875
|
-
/**
|
|
876
|
-
* Get the app context from the current component context
|
|
877
|
-
*/
|
|
878
|
-
function getAppContext(ctx) {
|
|
879
|
-
let current = ctx;
|
|
880
|
-
while (current) {
|
|
881
|
-
if (current._appContext) return current._appContext;
|
|
882
|
-
current = current.parent;
|
|
883
|
-
}
|
|
884
|
-
return null;
|
|
885
|
-
}
|
|
886
|
-
/**
|
|
887
|
-
* Inject the App instance (useful for plugins)
|
|
888
|
-
*/
|
|
889
|
-
function injectApp() {
|
|
890
|
-
return inject(AppContextKey);
|
|
891
|
-
}
|
|
892
|
-
function provide(token, value) {
|
|
893
|
-
const ctx = getCurrentInstance();
|
|
894
|
-
if (!ctx) {
|
|
895
|
-
console.warn("provide called outside of component setup");
|
|
896
|
-
return;
|
|
897
|
-
}
|
|
898
|
-
if (!ctx.provides) ctx.provides = /* @__PURE__ */ new Map();
|
|
899
|
-
ctx.provides.set(token, value);
|
|
900
|
-
}
|
|
901
|
-
const globalInstances = /* @__PURE__ */ new Map();
|
|
902
|
-
function defineInjectable(factory) {
|
|
903
|
-
const token = factory;
|
|
904
|
-
const useFn = () => {
|
|
905
|
-
const injected = inject(token);
|
|
906
|
-
if (injected) return injected;
|
|
907
|
-
if (!globalInstances.has(token)) globalInstances.set(token, factory());
|
|
908
|
-
return globalInstances.get(token);
|
|
909
|
-
};
|
|
910
|
-
useFn._factory = factory;
|
|
911
|
-
useFn._token = token;
|
|
912
|
-
return useFn;
|
|
913
|
-
}
|
|
914
|
-
function defineProvide(useFn) {
|
|
915
|
-
const factory = useFn._factory;
|
|
916
|
-
const token = useFn._token;
|
|
917
|
-
if (!factory || !token) throw new Error("defineProvide must be called with a function created by defineInjectable");
|
|
918
|
-
const instance = factory();
|
|
919
|
-
provide(token, instance);
|
|
920
|
-
return instance;
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
//#endregion
|
|
924
|
-
//#region src/di/factory.ts
|
|
925
686
|
var SubscriptionHandler = class {
|
|
926
|
-
|
|
687
|
+
constructor() {
|
|
688
|
+
this.unsubs = [];
|
|
689
|
+
}
|
|
927
690
|
add(unsub) {
|
|
928
691
|
this.unsubs.push(unsub);
|
|
929
692
|
}
|
|
@@ -949,7 +712,7 @@ function defineFactory(setup, lifetime, typeIdentifier) {
|
|
|
949
712
|
};
|
|
950
713
|
if (customDispose) customDispose(dispose);
|
|
951
714
|
else try {
|
|
952
|
-
|
|
715
|
+
onUnmounted(() => dispose());
|
|
953
716
|
} catch (e) {}
|
|
954
717
|
return {
|
|
955
718
|
...result,
|
|
@@ -959,155 +722,59 @@ function defineFactory(setup, lifetime, typeIdentifier) {
|
|
|
959
722
|
if (setup.length <= 1) return defineInjectable(() => factoryCreator());
|
|
960
723
|
return factoryCreator;
|
|
961
724
|
}
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
},
|
|
975
|
-
defineActions: (actions) => {
|
|
976
|
-
return defineActions(actions, id, messages);
|
|
977
|
-
}
|
|
978
|
-
}, ...args);
|
|
979
|
-
ctxFactory.onDeactivated(() => {
|
|
980
|
-
scope.stop();
|
|
981
|
-
messages?.forEach((m) => m.destroy());
|
|
982
|
-
messages = null;
|
|
983
|
-
});
|
|
984
|
-
if (!result.name) result.name = id;
|
|
985
|
-
return result;
|
|
986
|
-
}, lifetime);
|
|
725
|
+
const CLIENT_DIRECTIVE_PREFIX = "client:";
|
|
726
|
+
const CLIENT_DIRECTIVES = [
|
|
727
|
+
"client:load",
|
|
728
|
+
"client:idle",
|
|
729
|
+
"client:visible",
|
|
730
|
+
"client:media",
|
|
731
|
+
"client:only"
|
|
732
|
+
];
|
|
733
|
+
function filterClientDirectives(props) {
|
|
734
|
+
const filtered = {};
|
|
735
|
+
for (const key in props) if (!key.startsWith("client:")) filtered[key] = props[key];
|
|
736
|
+
return filtered;
|
|
987
737
|
}
|
|
988
|
-
function
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
onDispatched,
|
|
997
|
-
onFailure
|
|
738
|
+
function getHydrationDirective(props) {
|
|
739
|
+
if (props["client:load"] !== void 0) return { strategy: "load" };
|
|
740
|
+
if (props["client:idle"] !== void 0) return { strategy: "idle" };
|
|
741
|
+
if (props["client:visible"] !== void 0) return { strategy: "visible" };
|
|
742
|
+
if (props["client:only"] !== void 0) return { strategy: "only" };
|
|
743
|
+
if (props["client:media"] !== void 0) return {
|
|
744
|
+
strategy: "media",
|
|
745
|
+
media: props["client:media"]
|
|
998
746
|
};
|
|
999
|
-
|
|
1000
|
-
const name = `${actionName}.${type}`;
|
|
1001
|
-
if (!events[name]) {
|
|
1002
|
-
events[name] = createTopic({
|
|
1003
|
-
namespace,
|
|
1004
|
-
name
|
|
1005
|
-
});
|
|
1006
|
-
messages.push(events[name]);
|
|
1007
|
-
}
|
|
1008
|
-
return events[name];
|
|
1009
|
-
}
|
|
1010
|
-
Object.keys(actions).forEach((actionName) => {
|
|
1011
|
-
onDispatching[actionName] = { subscribe: (fn) => {
|
|
1012
|
-
return getEvent(actionName, "onDispatching").subscribe(function() {
|
|
1013
|
-
fn.apply(this, arguments[0]);
|
|
1014
|
-
});
|
|
1015
|
-
} };
|
|
1016
|
-
onDispatched[actionName] = { subscribe: (fn) => {
|
|
1017
|
-
return getEvent(actionName, "onDispatched").subscribe(function() {
|
|
1018
|
-
const msg = arguments[0];
|
|
1019
|
-
const allArguments = [msg.result].concat(Array.from(msg.args));
|
|
1020
|
-
fn.apply(this, allArguments);
|
|
1021
|
-
});
|
|
1022
|
-
} };
|
|
1023
|
-
onFailure[actionName] = { subscribe: (fn) => {
|
|
1024
|
-
return getEvent(actionName, "onFailure").subscribe(function() {
|
|
1025
|
-
const msg = arguments[0];
|
|
1026
|
-
const allArguments = [msg.reason].concat(Array.from(msg.args));
|
|
1027
|
-
fn.apply(this, allArguments);
|
|
1028
|
-
});
|
|
1029
|
-
} };
|
|
1030
|
-
result[actionName] = function() {
|
|
1031
|
-
try {
|
|
1032
|
-
const currentArguments = arguments;
|
|
1033
|
-
getEvent(actionName, "onDispatching").publish(currentArguments);
|
|
1034
|
-
const returnedResult = actions[actionName].apply(this, currentArguments);
|
|
1035
|
-
if (Utils.isPromise(returnedResult)) returnedResult.then((result$1) => {
|
|
1036
|
-
getEvent(actionName, "onDispatched").publish({
|
|
1037
|
-
result: returnedResult,
|
|
1038
|
-
args: currentArguments
|
|
1039
|
-
});
|
|
1040
|
-
});
|
|
1041
|
-
else getEvent(actionName, "onDispatched").publish({
|
|
1042
|
-
result: returnedResult,
|
|
1043
|
-
args: currentArguments
|
|
1044
|
-
});
|
|
1045
|
-
return returnedResult;
|
|
1046
|
-
} catch (err) {
|
|
1047
|
-
console.error(err);
|
|
1048
|
-
getEvent(actionName, "onFailure").publish({
|
|
1049
|
-
reason: err,
|
|
1050
|
-
args: arguments
|
|
1051
|
-
});
|
|
1052
|
-
}
|
|
1053
|
-
};
|
|
1054
|
-
});
|
|
1055
|
-
return result;
|
|
747
|
+
return null;
|
|
1056
748
|
}
|
|
1057
|
-
function
|
|
1058
|
-
const
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
console.error(err);
|
|
1078
|
-
}
|
|
1079
|
-
};
|
|
1080
|
-
const eventKey = `onMutated${key.charAt(0).toUpperCase()}${key.slice(1)}`;
|
|
1081
|
-
if (!events[eventKey]) {
|
|
1082
|
-
const topic = createTopic({
|
|
1083
|
-
namespace: `${storeInstanceName}.events`,
|
|
1084
|
-
name: eventKey
|
|
1085
|
-
});
|
|
1086
|
-
events[eventKey] = topic;
|
|
1087
|
-
messages.push(topic);
|
|
1088
|
-
}
|
|
1089
|
-
}
|
|
1090
|
-
function triggerEvent(name, value$1) {
|
|
1091
|
-
const keyString = name;
|
|
1092
|
-
events[`onMutated${keyString.charAt(0).toUpperCase()}${keyString.slice(1)}`]?.publish(value$1);
|
|
749
|
+
function hasClientDirective(props) {
|
|
750
|
+
for (const key in props) if (key.startsWith("client:")) return true;
|
|
751
|
+
return false;
|
|
752
|
+
}
|
|
753
|
+
function serializeProps(props) {
|
|
754
|
+
const filtered = filterClientDirectives(props);
|
|
755
|
+
const result = {};
|
|
756
|
+
let hasProps = false;
|
|
757
|
+
for (const key in filtered) {
|
|
758
|
+
const value = filtered[key];
|
|
759
|
+
if (key === "children" || key === "key" || key === "ref" || key === "slots") continue;
|
|
760
|
+
if (typeof value === "function") continue;
|
|
761
|
+
if (typeof value === "symbol") continue;
|
|
762
|
+
if (value === void 0) continue;
|
|
763
|
+
if (key.startsWith("on") && key.length > 2 && key[2] === key[2].toUpperCase()) continue;
|
|
764
|
+
try {
|
|
765
|
+
JSON.stringify(value);
|
|
766
|
+
result[key] = value;
|
|
767
|
+
hasProps = true;
|
|
768
|
+
} catch {}
|
|
1093
769
|
}
|
|
1094
|
-
|
|
1095
|
-
initProperty(key);
|
|
1096
|
-
});
|
|
1097
|
-
return {
|
|
1098
|
-
state,
|
|
1099
|
-
events,
|
|
1100
|
-
mutate
|
|
1101
|
-
};
|
|
770
|
+
return hasProps ? result : void 0;
|
|
1102
771
|
}
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
function isComponent(type) {
|
|
1110
|
-
return typeof type === "function" && "__setup" in type;
|
|
772
|
+
function createEmit(reactiveProps) {
|
|
773
|
+
return (event, ...args) => {
|
|
774
|
+
const eventName = `on${event[0].toUpperCase() + event.slice(1)}`;
|
|
775
|
+
const handler = ("value" in reactiveProps ? reactiveProps.value : reactiveProps)?.[eventName];
|
|
776
|
+
if (handler && typeof handler === "function") handler(...args);
|
|
777
|
+
};
|
|
1111
778
|
}
|
|
1112
779
|
function createRenderer(options) {
|
|
1113
780
|
const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, cloneNode: hostCloneNode, insertStaticContent: hostInsertStaticContent } = options;
|
|
@@ -1141,7 +808,72 @@ function createRenderer(options) {
|
|
|
1141
808
|
container._vnode = null;
|
|
1142
809
|
}
|
|
1143
810
|
}
|
|
1144
|
-
|
|
811
|
+
const svgTags = new Set([
|
|
812
|
+
"svg",
|
|
813
|
+
"animate",
|
|
814
|
+
"animateMotion",
|
|
815
|
+
"animateTransform",
|
|
816
|
+
"circle",
|
|
817
|
+
"clipPath",
|
|
818
|
+
"defs",
|
|
819
|
+
"desc",
|
|
820
|
+
"ellipse",
|
|
821
|
+
"feBlend",
|
|
822
|
+
"feColorMatrix",
|
|
823
|
+
"feComponentTransfer",
|
|
824
|
+
"feComposite",
|
|
825
|
+
"feConvolveMatrix",
|
|
826
|
+
"feDiffuseLighting",
|
|
827
|
+
"feDisplacementMap",
|
|
828
|
+
"feDistantLight",
|
|
829
|
+
"feDropShadow",
|
|
830
|
+
"feFlood",
|
|
831
|
+
"feFuncA",
|
|
832
|
+
"feFuncB",
|
|
833
|
+
"feFuncG",
|
|
834
|
+
"feFuncR",
|
|
835
|
+
"feGaussianBlur",
|
|
836
|
+
"feImage",
|
|
837
|
+
"feMerge",
|
|
838
|
+
"feMergeNode",
|
|
839
|
+
"feMorphology",
|
|
840
|
+
"feOffset",
|
|
841
|
+
"fePointLight",
|
|
842
|
+
"feSpecularLighting",
|
|
843
|
+
"feSpotLight",
|
|
844
|
+
"feTile",
|
|
845
|
+
"feTurbulence",
|
|
846
|
+
"filter",
|
|
847
|
+
"foreignObject",
|
|
848
|
+
"g",
|
|
849
|
+
"image",
|
|
850
|
+
"line",
|
|
851
|
+
"linearGradient",
|
|
852
|
+
"marker",
|
|
853
|
+
"mask",
|
|
854
|
+
"metadata",
|
|
855
|
+
"mpath",
|
|
856
|
+
"path",
|
|
857
|
+
"pattern",
|
|
858
|
+
"polygon",
|
|
859
|
+
"polyline",
|
|
860
|
+
"radialGradient",
|
|
861
|
+
"rect",
|
|
862
|
+
"set",
|
|
863
|
+
"stop",
|
|
864
|
+
"switch",
|
|
865
|
+
"symbol",
|
|
866
|
+
"text",
|
|
867
|
+
"textPath",
|
|
868
|
+
"title",
|
|
869
|
+
"tspan",
|
|
870
|
+
"use",
|
|
871
|
+
"view"
|
|
872
|
+
]);
|
|
873
|
+
function isSvgTag(tag) {
|
|
874
|
+
return svgTags.has(tag);
|
|
875
|
+
}
|
|
876
|
+
function mount(vnode, container, before = null, parentIsSVG = false) {
|
|
1145
877
|
if (vnode == null || vnode === false || vnode === true) return;
|
|
1146
878
|
if (vnode.type === Text) {
|
|
1147
879
|
const node = hostCreateText(String(vnode.text));
|
|
@@ -1154,26 +886,29 @@ function createRenderer(options) {
|
|
|
1154
886
|
const anchor = hostCreateComment("");
|
|
1155
887
|
vnode.dom = anchor;
|
|
1156
888
|
hostInsert(anchor, container, before);
|
|
1157
|
-
if (vnode.children) vnode.children.forEach((child) => mount(child, container, anchor));
|
|
889
|
+
if (vnode.children) vnode.children.forEach((child) => mount(child, container, anchor, parentIsSVG));
|
|
1158
890
|
return;
|
|
1159
891
|
}
|
|
1160
892
|
if (isComponent(vnode.type)) {
|
|
1161
893
|
mountComponent(vnode, container, before, vnode.type.__setup);
|
|
1162
894
|
return;
|
|
1163
895
|
}
|
|
1164
|
-
const
|
|
896
|
+
const tag = vnode.type;
|
|
897
|
+
const isSVG = tag === "svg" || parentIsSVG && tag !== "foreignObject";
|
|
898
|
+
const element = hostCreateElement(tag, isSVG);
|
|
1165
899
|
vnode.dom = element;
|
|
1166
900
|
element.__vnode = vnode;
|
|
1167
901
|
if (vnode.props) {
|
|
1168
|
-
for (const key in vnode.props) if (key !== "children" && key !== "key" && key !== "ref") hostPatchProp(element, key, null, vnode.props[key]);
|
|
1169
|
-
if (vnode.props.ref) {
|
|
902
|
+
for (const key in vnode.props) if (key !== "children" && key !== "key" && key !== "ref") hostPatchProp(element, key, null, vnode.props[key], isSVG);
|
|
903
|
+
if (vnode.props.ref) untrack(() => {
|
|
1170
904
|
if (typeof vnode.props.ref === "function") vnode.props.ref(element);
|
|
1171
905
|
else if (typeof vnode.props.ref === "object") vnode.props.ref.current = element;
|
|
1172
|
-
}
|
|
906
|
+
});
|
|
1173
907
|
}
|
|
908
|
+
const childIsSVG = isSVG && tag !== "foreignObject";
|
|
1174
909
|
if (vnode.children) vnode.children.forEach((child) => {
|
|
1175
910
|
child.parent = vnode;
|
|
1176
|
-
mount(child, element);
|
|
911
|
+
mount(child, element, null, childIsSVG);
|
|
1177
912
|
});
|
|
1178
913
|
hostInsert(element, container, before);
|
|
1179
914
|
}
|
|
@@ -1185,10 +920,10 @@ function createRenderer(options) {
|
|
|
1185
920
|
const subTree = internalVNode._subTree;
|
|
1186
921
|
if (subTree) unmount(subTree, container);
|
|
1187
922
|
if (vnode.dom) hostRemove(vnode.dom);
|
|
1188
|
-
if (vnode.props?.ref) {
|
|
923
|
+
if (vnode.props?.ref) untrack(() => {
|
|
1189
924
|
if (typeof vnode.props.ref === "function") vnode.props.ref(null);
|
|
1190
925
|
else if (typeof vnode.props.ref === "object") vnode.props.ref.current = null;
|
|
1191
|
-
}
|
|
926
|
+
});
|
|
1192
927
|
return;
|
|
1193
928
|
}
|
|
1194
929
|
if (vnode.type === Fragment) {
|
|
@@ -1196,10 +931,10 @@ function createRenderer(options) {
|
|
|
1196
931
|
if (vnode.dom) hostRemove(vnode.dom);
|
|
1197
932
|
return;
|
|
1198
933
|
}
|
|
1199
|
-
if (vnode.props?.ref) {
|
|
934
|
+
if (vnode.props?.ref) untrack(() => {
|
|
1200
935
|
if (typeof vnode.props.ref === "function") vnode.props.ref(null);
|
|
1201
936
|
else if (vnode.props.ref && typeof vnode.props.ref === "object") vnode.props.ref.current = null;
|
|
1202
|
-
}
|
|
937
|
+
});
|
|
1203
938
|
if (vnode.children && vnode.children.length > 0) vnode.children.forEach((child) => unmount(child, vnode.dom));
|
|
1204
939
|
if (vnode.dom) hostRemove(vnode.dom);
|
|
1205
940
|
}
|
|
@@ -1207,7 +942,7 @@ function createRenderer(options) {
|
|
|
1207
942
|
if (oldVNode === newVNode) return;
|
|
1208
943
|
if (!isSameVNode(oldVNode, newVNode)) {
|
|
1209
944
|
const parent = hostParentNode(oldVNode.dom) || container;
|
|
1210
|
-
const nextSibling = hostNextSibling(oldVNode.dom);
|
|
945
|
+
const nextSibling = oldVNode.dom ? hostNextSibling(oldVNode.dom) : null;
|
|
1211
946
|
unmount(oldVNode, parent);
|
|
1212
947
|
mount(newVNode, parent, nextSibling);
|
|
1213
948
|
return;
|
|
@@ -1222,12 +957,25 @@ function createRenderer(options) {
|
|
|
1222
957
|
const props = oldInternal._componentProps;
|
|
1223
958
|
newInternal._componentProps = props;
|
|
1224
959
|
if (props) {
|
|
1225
|
-
const newProps
|
|
960
|
+
const newProps = newVNode.props || {};
|
|
961
|
+
const newModels = newVNode.props?.$models || {};
|
|
1226
962
|
untrack(() => {
|
|
1227
|
-
for (const key in newProps
|
|
1228
|
-
if (props[key] !== newProps
|
|
963
|
+
for (const key in newProps) if (key !== "children" && key !== "key" && key !== "ref" && key !== "$models") {
|
|
964
|
+
if (props[key] !== newProps[key]) props[key] = newProps[key];
|
|
965
|
+
}
|
|
966
|
+
for (const modelKey in newModels) {
|
|
967
|
+
const newModel = newModels[modelKey];
|
|
968
|
+
const oldModel = props[modelKey];
|
|
969
|
+
if (isModel(newModel)) {
|
|
970
|
+
if (isModel(oldModel)) {
|
|
971
|
+
const [newObj, newKey] = newModel.binding;
|
|
972
|
+
const [oldObj, oldKey] = oldModel.binding;
|
|
973
|
+
if (newObj === oldObj && newKey === oldKey) continue;
|
|
974
|
+
}
|
|
975
|
+
props[modelKey] = newModel;
|
|
976
|
+
}
|
|
1229
977
|
}
|
|
1230
|
-
for (const key in props) if (!(key in newProps
|
|
978
|
+
for (const key in props) if (!(key in newProps) && !(key in newModels) && key !== "children" && key !== "key" && key !== "ref" && key !== "$models") delete props[key];
|
|
1231
979
|
});
|
|
1232
980
|
}
|
|
1233
981
|
const slotsRef = oldInternal._slots;
|
|
@@ -1255,27 +1003,43 @@ function createRenderer(options) {
|
|
|
1255
1003
|
return;
|
|
1256
1004
|
}
|
|
1257
1005
|
if (newVNode.type === Fragment) {
|
|
1258
|
-
patchChildren(oldVNode, newVNode, container);
|
|
1006
|
+
patchChildren(oldVNode, newVNode, container, false);
|
|
1259
1007
|
return;
|
|
1260
1008
|
}
|
|
1261
1009
|
const element = newVNode.dom = oldVNode.dom;
|
|
1010
|
+
if (!element) {
|
|
1011
|
+
mount(newVNode, container);
|
|
1012
|
+
return;
|
|
1013
|
+
}
|
|
1014
|
+
const tag = newVNode.type;
|
|
1015
|
+
const isSVG = tag === "svg" || isSvgTag(tag);
|
|
1262
1016
|
const oldProps = oldVNode.props || {};
|
|
1263
1017
|
const newProps = newVNode.props || {};
|
|
1264
|
-
for (const key in oldProps) if (!(key in newProps) && key !== "children" && key !== "key" && key !== "ref") hostPatchProp(element, key, oldProps[key], null);
|
|
1018
|
+
for (const key in oldProps) if (!(key in newProps) && key !== "children" && key !== "key" && key !== "ref") hostPatchProp(element, key, oldProps[key], null, isSVG);
|
|
1265
1019
|
for (const key in newProps) {
|
|
1266
1020
|
const oldValue = oldProps[key];
|
|
1267
1021
|
const newValue = newProps[key];
|
|
1268
|
-
if (key !== "children" && key !== "key" && key !== "ref" && oldValue !== newValue) hostPatchProp(element, key, oldValue, newValue);
|
|
1022
|
+
if (key !== "children" && key !== "key" && key !== "ref" && oldValue !== newValue) hostPatchProp(element, key, oldValue, newValue, isSVG);
|
|
1269
1023
|
}
|
|
1270
|
-
patchChildren(oldVNode, newVNode, element);
|
|
1024
|
+
patchChildren(oldVNode, newVNode, element, isSVG && tag !== "foreignObject");
|
|
1271
1025
|
}
|
|
1272
|
-
function patchChildren(oldVNode, newVNode, container) {
|
|
1026
|
+
function patchChildren(oldVNode, newVNode, container, parentIsSVG = false) {
|
|
1273
1027
|
const oldChildren = oldVNode.children;
|
|
1274
1028
|
const newChildren = newVNode.children;
|
|
1275
1029
|
newChildren.forEach((c) => c.parent = newVNode);
|
|
1276
|
-
reconcileChildrenArray(container, oldChildren, newChildren);
|
|
1030
|
+
reconcileChildrenArray(container, oldChildren, newChildren, parentIsSVG);
|
|
1277
1031
|
}
|
|
1278
|
-
function
|
|
1032
|
+
function checkDuplicateKeys(children) {
|
|
1033
|
+
if (process.env.NODE_ENV === "production") return;
|
|
1034
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
1035
|
+
for (const child of children) if (child?.key != null) {
|
|
1036
|
+
const keyStr = String(child.key);
|
|
1037
|
+
if (seenKeys.has(keyStr)) console.warn(`[SignalX] Duplicate key "${child.key}" detected in list. Keys should be unique among siblings to ensure correct reconciliation. This may cause unexpected behavior when items are reordered, added, or removed.`);
|
|
1038
|
+
seenKeys.add(keyStr);
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
function reconcileChildrenArray(parent, oldChildren, newChildren, parentIsSVG = false) {
|
|
1042
|
+
if (process.env.NODE_ENV !== "production") checkDuplicateKeys(newChildren);
|
|
1279
1043
|
let oldStartIdx = 0;
|
|
1280
1044
|
let oldEndIdx = oldChildren.length - 1;
|
|
1281
1045
|
let oldStartVNode = oldChildren[0];
|
|
@@ -1317,13 +1081,13 @@ function createRenderer(options) {
|
|
|
1317
1081
|
patch(vnodeToMove, newStartVNode, parent);
|
|
1318
1082
|
oldChildren[idxInOld] = void 0;
|
|
1319
1083
|
if (vnodeToMove.dom && oldStartVNode.dom) hostInsert(vnodeToMove.dom, parent, oldStartVNode.dom);
|
|
1320
|
-
} else mount(newStartVNode, parent, oldStartVNode.dom);
|
|
1084
|
+
} else mount(newStartVNode, parent, oldStartVNode.dom, parentIsSVG);
|
|
1321
1085
|
newStartVNode = newChildren[++newStartIdx];
|
|
1322
1086
|
}
|
|
1323
1087
|
if (oldStartIdx > oldEndIdx) {
|
|
1324
1088
|
if (newStartIdx <= newEndIdx) {
|
|
1325
1089
|
const anchor = newChildren[newEndIdx + 1] == null ? null : newChildren[newEndIdx + 1].dom;
|
|
1326
|
-
for (let i = newStartIdx; i <= newEndIdx; i++) mount(newChildren[i], parent, anchor);
|
|
1090
|
+
for (let i = newStartIdx; i <= newEndIdx; i++) mount(newChildren[i], parent, anchor, parentIsSVG);
|
|
1327
1091
|
}
|
|
1328
1092
|
} else if (newStartIdx > newEndIdx) {
|
|
1329
1093
|
for (let i = oldStartIdx; i <= oldEndIdx; i++) if (oldChildren[i]) unmount(oldChildren[i], parent);
|
|
@@ -1340,7 +1104,11 @@ function createRenderer(options) {
|
|
|
1340
1104
|
const map = /* @__PURE__ */ new Map();
|
|
1341
1105
|
for (let i = beginIdx; i <= endIdx; i++) {
|
|
1342
1106
|
const key = children[i]?.key;
|
|
1343
|
-
if (key != null)
|
|
1107
|
+
if (key != null) {
|
|
1108
|
+
const keyStr = String(key);
|
|
1109
|
+
if (process.env.NODE_ENV !== "production" && map.has(keyStr)) console.warn(`[SignalX] Duplicate key "${key}" detected in list. Keys should be unique among siblings to ensure correct reconciliation. This may cause unexpected behavior when items are reordered, added, or removed.`);
|
|
1110
|
+
map.set(keyStr, i);
|
|
1111
|
+
}
|
|
1344
1112
|
}
|
|
1345
1113
|
return map;
|
|
1346
1114
|
}
|
|
@@ -1355,14 +1123,21 @@ function createRenderer(options) {
|
|
|
1355
1123
|
hostInsert(anchor, container, before);
|
|
1356
1124
|
let exposed = null;
|
|
1357
1125
|
let exposeCalled = false;
|
|
1358
|
-
const { children, slots: slotsFromProps, ...propsData } = vnode.props || {};
|
|
1359
|
-
const
|
|
1126
|
+
const { children, slots: slotsFromProps, $models: modelsData, ...propsData } = vnode.props || {};
|
|
1127
|
+
const propsWithModels = { ...propsData };
|
|
1128
|
+
if (modelsData) for (const modelKey in modelsData) {
|
|
1129
|
+
const modelValue = modelsData[modelKey];
|
|
1130
|
+
if (isModel(modelValue)) propsWithModels[modelKey] = modelValue;
|
|
1131
|
+
}
|
|
1132
|
+
const reactiveProps = signal$1(propsWithModels);
|
|
1360
1133
|
const internalVNode = vnode;
|
|
1361
1134
|
internalVNode._componentProps = reactiveProps;
|
|
1362
1135
|
const slots = createSlots(children, slotsFromProps);
|
|
1363
1136
|
internalVNode._slots = slots;
|
|
1137
|
+
const createdHooks = [];
|
|
1364
1138
|
const mountHooks = [];
|
|
1365
|
-
const
|
|
1139
|
+
const updatedHooks = [];
|
|
1140
|
+
const unmountHooks = [];
|
|
1366
1141
|
const parentInstance = getCurrentInstance();
|
|
1367
1142
|
const componentName = vnode.type.__name;
|
|
1368
1143
|
const ctx = {
|
|
@@ -1370,16 +1145,19 @@ function createRenderer(options) {
|
|
|
1370
1145
|
signal: signal$1,
|
|
1371
1146
|
props: createPropsAccessor(reactiveProps),
|
|
1372
1147
|
slots,
|
|
1373
|
-
emit: (
|
|
1374
|
-
const handler = reactiveProps[`on${event[0].toUpperCase() + event.slice(1)}`];
|
|
1375
|
-
if (handler && typeof handler === "function") handler(...args);
|
|
1376
|
-
},
|
|
1148
|
+
emit: createEmit(reactiveProps),
|
|
1377
1149
|
parent: parentInstance,
|
|
1378
|
-
|
|
1150
|
+
onMounted: (fn) => {
|
|
1379
1151
|
mountHooks.push(fn);
|
|
1380
1152
|
},
|
|
1381
|
-
|
|
1382
|
-
|
|
1153
|
+
onUnmounted: (fn) => {
|
|
1154
|
+
unmountHooks.push(fn);
|
|
1155
|
+
},
|
|
1156
|
+
onCreated: (fn) => {
|
|
1157
|
+
createdHooks.push(fn);
|
|
1158
|
+
},
|
|
1159
|
+
onUpdated: (fn) => {
|
|
1160
|
+
updatedHooks.push(fn);
|
|
1383
1161
|
},
|
|
1384
1162
|
expose: (exposedValue) => {
|
|
1385
1163
|
exposed = exposedValue;
|
|
@@ -1390,7 +1168,7 @@ function createRenderer(options) {
|
|
|
1390
1168
|
};
|
|
1391
1169
|
applyContextExtensions(ctx);
|
|
1392
1170
|
ctx.__name = componentName;
|
|
1393
|
-
if (currentAppContext) ctx
|
|
1171
|
+
if (!parentInstance && currentAppContext) provideAppContext(ctx, currentAppContext);
|
|
1394
1172
|
const componentInstance = {
|
|
1395
1173
|
name: componentName,
|
|
1396
1174
|
ctx,
|
|
@@ -1400,9 +1178,10 @@ function createRenderer(options) {
|
|
|
1400
1178
|
let renderFn;
|
|
1401
1179
|
try {
|
|
1402
1180
|
const setupResult = setup(ctx);
|
|
1403
|
-
if (setupResult && typeof setupResult.then === "function") throw new Error(`Async setup in component "${componentName}" is only supported during SSR. On the client, use pre-loaded data from hydration or fetch in
|
|
1181
|
+
if (setupResult && typeof setupResult.then === "function") throw new Error(`Async setup in component "${componentName}" is only supported during SSR. On the client, use pre-loaded data from hydration or fetch in onMounted.`);
|
|
1404
1182
|
renderFn = setupResult;
|
|
1405
1183
|
notifyComponentCreated(currentAppContext, componentInstance);
|
|
1184
|
+
createdHooks.forEach((hook) => hook());
|
|
1406
1185
|
} catch (err) {
|
|
1407
1186
|
if (!handleComponentError(currentAppContext, err, componentInstance, "setup")) throw err;
|
|
1408
1187
|
} finally {
|
|
@@ -1410,8 +1189,10 @@ function createRenderer(options) {
|
|
|
1410
1189
|
}
|
|
1411
1190
|
if (vnode.props?.ref) {
|
|
1412
1191
|
const refValue = exposeCalled ? exposed : null;
|
|
1413
|
-
|
|
1414
|
-
|
|
1192
|
+
untrack(() => {
|
|
1193
|
+
if (typeof vnode.props.ref === "function") vnode.props.ref(refValue);
|
|
1194
|
+
else if (vnode.props.ref && typeof vnode.props.ref === "object") vnode.props.ref.current = refValue;
|
|
1195
|
+
});
|
|
1415
1196
|
}
|
|
1416
1197
|
if (renderFn) {
|
|
1417
1198
|
ctx.renderFn = renderFn;
|
|
@@ -1425,6 +1206,7 @@ function createRenderer(options) {
|
|
|
1425
1206
|
if (prevSubTree) {
|
|
1426
1207
|
patch(prevSubTree, subTree, container);
|
|
1427
1208
|
notifyComponentUpdated(currentAppContext, componentInstance);
|
|
1209
|
+
updatedHooks.forEach((hook) => hook());
|
|
1428
1210
|
} else mount(subTree, container, anchor);
|
|
1429
1211
|
internalVNode._subTree = subTree;
|
|
1430
1212
|
} catch (err) {
|
|
@@ -1443,7 +1225,7 @@ function createRenderer(options) {
|
|
|
1443
1225
|
notifyComponentMounted(currentAppContext, componentInstance);
|
|
1444
1226
|
vnode.cleanup = () => {
|
|
1445
1227
|
notifyComponentUnmounted(currentAppContext, componentInstance);
|
|
1446
|
-
|
|
1228
|
+
unmountHooks.forEach((hook) => hook(mountCtx));
|
|
1447
1229
|
};
|
|
1448
1230
|
}
|
|
1449
1231
|
return {
|
|
@@ -1451,23 +1233,9 @@ function createRenderer(options) {
|
|
|
1451
1233
|
patch,
|
|
1452
1234
|
mount,
|
|
1453
1235
|
unmount,
|
|
1454
|
-
mountComponent
|
|
1455
|
-
createApp: (rootComponent) => {
|
|
1456
|
-
return { mount(selectorOrContainer) {
|
|
1457
|
-
let container = null;
|
|
1458
|
-
if (typeof selectorOrContainer === "string") {
|
|
1459
|
-
if (options.querySelector) container = options.querySelector(selectorOrContainer);
|
|
1460
|
-
} else container = selectorOrContainer;
|
|
1461
|
-
if (!container) {
|
|
1462
|
-
console.warn(`Container not found: ${selectorOrContainer}`);
|
|
1463
|
-
return;
|
|
1464
|
-
}
|
|
1465
|
-
render(rootComponent, container);
|
|
1466
|
-
} };
|
|
1467
|
-
}
|
|
1236
|
+
mountComponent
|
|
1468
1237
|
};
|
|
1469
1238
|
}
|
|
1239
|
+
export { CLIENT_DIRECTIVES, CLIENT_DIRECTIVE_PREFIX, Fragment, InstanceLifetimes, SubscriptionHandler, Suspense, Text, Utils, applyContextExtensions, component, compound, createEmit, createModel, createModelFromBinding, createPropsAccessor, createPropsProxy, createRenderer, createSlots, createTopic, defineApp, defineFactory, defineInjectable, defineProvide, filterClientDirectives, getAppContextToken, getComponentMeta, getComponentPlugins, getCurrentInstance, getDefaultMount, getHydrationDirective, getModelSymbol, getPlatformModelProcessor, guid, handleComponentError, hasClientDirective, isComponent, isLazyComponent, isModel, jsx, jsxDEV, jsxs, lazy, normalizeSubTree, notifyComponentCreated, notifyComponentMounted, notifyComponentUnmounted, notifyComponentUpdated, onCreated, onMounted, onUnmounted, onUpdated, provideAppContext, registerComponentPlugin, registerContextExtension, registerPendingPromise, serializeProps, setCurrentInstance, setDefaultMount, setPlatformModelProcessor, signal, toSubscriber, useAppContext, valueOf };
|
|
1470
1240
|
|
|
1471
|
-
//#endregion
|
|
1472
|
-
export { AppContextKey, Fragment, InstanceLifetimes, SubscriptionHandler, Suspense, Text, Utils, applyContextExtensions, createPropsAccessor, createPropsProxy, createRenderer, createSlots, createTopic, defineApp, defineComponent, defineFactory, defineInjectable, defineProvide, defineStore, getComponentMeta, getComponentPlugins, getCurrentInstance, getDefaultMount, getPlatformSyncProcessor, guid, handleComponentError, inject, injectApp, isLazyComponent, jsx, jsxDEV, jsxs, lazy, normalizeSubTree, notifyComponentCreated, notifyComponentMounted, notifyComponentUnmounted, notifyComponentUpdated, onCleanup, onMount, provide, registerComponentPlugin, registerContextExtension, registerPendingPromise, setCurrentInstance, setDefaultMount, setPlatformSyncProcessor, signal, toSubscriber, valueOf };
|
|
1473
1241
|
//# sourceMappingURL=index.js.map
|