@sigx/runtime-core 0.1.4 → 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 +147 -39
- 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 +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +556 -682
- 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/plugins.d.ts +25 -1
- package/dist/plugins.d.ts.map +1 -1
- package/dist/renderer.d.ts +22 -21
- 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 +34 -0
- package/dist/utils/normalize.d.ts.map +1 -0
- package/dist/utils/props-accessor.d.ts +20 -0
- package/dist/utils/props-accessor.d.ts.map +1 -0
- package/dist/utils/slots.d.ts +46 -0
- package/dist/utils/slots.d.ts.map +1 -0
- 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/index.js
CHANGED
|
@@ -1,84 +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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
16
|
+
var contextExtensions = [];
|
|
17
|
+
function registerContextExtension(extension) {
|
|
18
|
+
contextExtensions.push(extension);
|
|
19
|
+
}
|
|
20
|
+
function applyContextExtensions(ctx) {
|
|
21
|
+
for (const extension of contextExtensions) extension(ctx);
|
|
22
|
+
}
|
|
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;
|
|
51
131
|
function setDefaultMount(mountFn) {
|
|
52
132
|
defaultMountFn = mountFn;
|
|
53
133
|
}
|
|
54
|
-
/**
|
|
55
|
-
* Get the current default mount function.
|
|
56
|
-
* @internal
|
|
57
|
-
*/
|
|
58
134
|
function getDefaultMount() {
|
|
59
135
|
return defaultMountFn;
|
|
60
136
|
}
|
|
61
|
-
/**
|
|
62
|
-
* Create an application instance.
|
|
63
|
-
*
|
|
64
|
-
* @example
|
|
65
|
-
* ```tsx
|
|
66
|
-
* import { defineApp, defineInjectable } from '@sigx/runtime-core';
|
|
67
|
-
* import { render } from '@sigx/runtime-dom';
|
|
68
|
-
*
|
|
69
|
-
* // Define an injectable service
|
|
70
|
-
* const useApiConfig = defineInjectable(() => ({ baseUrl: 'https://api.example.com' }));
|
|
71
|
-
*
|
|
72
|
-
* const app = defineApp(<App />);
|
|
73
|
-
*
|
|
74
|
-
* app.use(myPlugin, { option: 'value' });
|
|
75
|
-
*
|
|
76
|
-
* // Provide using the injectable token (works with inject())
|
|
77
|
-
* app.provide(useApiConfig, { baseUrl: 'https://custom.api.com' });
|
|
78
|
-
*
|
|
79
|
-
* app.mount(document.getElementById('app')!, render);
|
|
80
|
-
* ```
|
|
81
|
-
*/
|
|
82
137
|
function defineApp(rootComponent) {
|
|
83
138
|
const installedPlugins = /* @__PURE__ */ new Set();
|
|
84
139
|
const context = {
|
|
@@ -103,11 +158,13 @@ function defineApp(rootComponent) {
|
|
|
103
158
|
else if (isDev) console.warn("Invalid plugin: must be a function or have an install() method.");
|
|
104
159
|
return app;
|
|
105
160
|
},
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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;
|
|
111
168
|
},
|
|
112
169
|
hook(hooks) {
|
|
113
170
|
context.hooks.push(hooks);
|
|
@@ -144,15 +201,16 @@ function defineApp(rootComponent) {
|
|
|
144
201
|
},
|
|
145
202
|
get _container() {
|
|
146
203
|
return container;
|
|
204
|
+
},
|
|
205
|
+
get _rootComponent() {
|
|
206
|
+
return rootComponent;
|
|
147
207
|
}
|
|
148
208
|
};
|
|
149
209
|
context.app = app;
|
|
210
|
+
const appContextToken = getAppContextToken();
|
|
211
|
+
context.provides.set(appContextToken, context);
|
|
150
212
|
return app;
|
|
151
213
|
}
|
|
152
|
-
/**
|
|
153
|
-
* Notify all app hooks that a component was created.
|
|
154
|
-
* Called by the renderer after setup() returns.
|
|
155
|
-
*/
|
|
156
214
|
function notifyComponentCreated(context, instance) {
|
|
157
215
|
if (!context) return;
|
|
158
216
|
for (const hooks of context.hooks) try {
|
|
@@ -161,10 +219,6 @@ function notifyComponentCreated(context, instance) {
|
|
|
161
219
|
handleHookError(context, err, instance, "onComponentCreated");
|
|
162
220
|
}
|
|
163
221
|
}
|
|
164
|
-
/**
|
|
165
|
-
* Notify all app hooks that a component was mounted.
|
|
166
|
-
* Called by the renderer after mount hooks run.
|
|
167
|
-
*/
|
|
168
222
|
function notifyComponentMounted(context, instance) {
|
|
169
223
|
if (!context) return;
|
|
170
224
|
for (const hooks of context.hooks) try {
|
|
@@ -173,10 +227,6 @@ function notifyComponentMounted(context, instance) {
|
|
|
173
227
|
handleHookError(context, err, instance, "onComponentMounted");
|
|
174
228
|
}
|
|
175
229
|
}
|
|
176
|
-
/**
|
|
177
|
-
* Notify all app hooks that a component was unmounted.
|
|
178
|
-
* Called by the renderer before cleanup.
|
|
179
|
-
*/
|
|
180
230
|
function notifyComponentUnmounted(context, instance) {
|
|
181
231
|
if (!context) return;
|
|
182
232
|
for (const hooks of context.hooks) try {
|
|
@@ -185,10 +235,6 @@ function notifyComponentUnmounted(context, instance) {
|
|
|
185
235
|
handleHookError(context, err, instance, "onComponentUnmounted");
|
|
186
236
|
}
|
|
187
237
|
}
|
|
188
|
-
/**
|
|
189
|
-
* Notify all app hooks that a component updated.
|
|
190
|
-
* Called by the renderer after re-render.
|
|
191
|
-
*/
|
|
192
238
|
function notifyComponentUpdated(context, instance) {
|
|
193
239
|
if (!context) return;
|
|
194
240
|
for (const hooks of context.hooks) try {
|
|
@@ -197,10 +243,6 @@ function notifyComponentUpdated(context, instance) {
|
|
|
197
243
|
handleHookError(context, err, instance, "onComponentUpdated");
|
|
198
244
|
}
|
|
199
245
|
}
|
|
200
|
-
/**
|
|
201
|
-
* Handle an error in a component. Returns true if the error was handled.
|
|
202
|
-
* Called by the renderer when an error occurs in setup or render.
|
|
203
|
-
*/
|
|
204
246
|
function handleComponentError(context, err, instance, info) {
|
|
205
247
|
if (!context) return false;
|
|
206
248
|
for (const hooks of context.hooks) try {
|
|
@@ -215,104 +257,53 @@ function handleComponentError(context, err, instance, info) {
|
|
|
215
257
|
}
|
|
216
258
|
return false;
|
|
217
259
|
}
|
|
218
|
-
/**
|
|
219
|
-
* Handle errors that occur in hooks themselves
|
|
220
|
-
*/
|
|
221
260
|
function handleHookError(context, err, instance, hookName) {
|
|
222
261
|
console.error(`Error in ${hookName} hook:`, err);
|
|
223
262
|
if (context.config.errorHandler) try {
|
|
224
263
|
context.config.errorHandler(err, instance, `plugin hook: ${hookName}`);
|
|
225
264
|
} catch {}
|
|
226
265
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
//#region src/component.ts
|
|
230
|
-
let currentComponentContext = null;
|
|
231
|
-
function getCurrentInstance() {
|
|
232
|
-
return currentComponentContext;
|
|
233
|
-
}
|
|
234
|
-
function setCurrentInstance(ctx) {
|
|
235
|
-
const prev = currentComponentContext;
|
|
236
|
-
currentComponentContext = ctx;
|
|
237
|
-
return prev;
|
|
266
|
+
function compound(main, sub) {
|
|
267
|
+
return Object.assign(main, sub);
|
|
238
268
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
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
|
+
};
|
|
242
288
|
}
|
|
243
|
-
function
|
|
244
|
-
|
|
245
|
-
|
|
289
|
+
function createModelFromBinding(binding) {
|
|
290
|
+
const [obj, key, handler] = binding;
|
|
291
|
+
return createModel([obj, key], handler);
|
|
246
292
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
* Get component metadata (for DevTools)
|
|
250
|
-
*/
|
|
251
|
-
function getComponentMeta(factory) {
|
|
252
|
-
return componentRegistry.get(factory);
|
|
293
|
+
function isModel(value) {
|
|
294
|
+
return value !== null && typeof value === "object" && MODEL_SYMBOL in value && value[MODEL_SYMBOL] === true;
|
|
253
295
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
*/
|
|
257
|
-
function createPropsProxy(target, onAccess) {
|
|
258
|
-
return new Proxy(target, { get(obj, prop) {
|
|
259
|
-
if (typeof prop === "string" && onAccess) onAccess(prop);
|
|
260
|
-
return obj[prop];
|
|
261
|
-
} });
|
|
296
|
+
function getModelSymbol() {
|
|
297
|
+
return MODEL_SYMBOL;
|
|
262
298
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
*
|
|
266
|
-
* @param setup - Setup function that receives context and returns a render function
|
|
267
|
-
* @param options - Optional configuration (e.g., name for DevTools)
|
|
268
|
-
*
|
|
269
|
-
* @example
|
|
270
|
-
* ```tsx
|
|
271
|
-
* type CardProps = DefineProp<"title", string> & DefineSlot<"header">;
|
|
272
|
-
*
|
|
273
|
-
* export const Card = defineComponent<CardProps>((ctx) => {
|
|
274
|
-
* const { title } = ctx.props;
|
|
275
|
-
* const { slots } = ctx;
|
|
276
|
-
*
|
|
277
|
-
* return () => (
|
|
278
|
-
* <div class="card">
|
|
279
|
-
* {slots.header?.() ?? <h2>{title}</h2>}
|
|
280
|
-
* {slots.default()}
|
|
281
|
-
* </div>
|
|
282
|
-
* );
|
|
283
|
-
* });
|
|
284
|
-
* ```
|
|
285
|
-
*/
|
|
286
|
-
function defineComponent(setup, options) {
|
|
287
|
-
const factory = function(props) {
|
|
288
|
-
return {
|
|
289
|
-
type: factory,
|
|
290
|
-
props: props || {},
|
|
291
|
-
key: props?.key || null,
|
|
292
|
-
children: [],
|
|
293
|
-
dom: null
|
|
294
|
-
};
|
|
295
|
-
};
|
|
296
|
-
factory.__setup = setup;
|
|
297
|
-
factory.__name = options?.name;
|
|
298
|
-
factory.__props = null;
|
|
299
|
-
factory.__events = null;
|
|
300
|
-
factory.__ref = null;
|
|
301
|
-
factory.__slots = null;
|
|
302
|
-
componentRegistry.set(factory, {
|
|
303
|
-
name: options?.name,
|
|
304
|
-
setup
|
|
305
|
-
});
|
|
306
|
-
getComponentPlugins().forEach((p) => p.onDefine?.(options?.name, factory, setup));
|
|
307
|
-
return factory;
|
|
299
|
+
function isComponent(type) {
|
|
300
|
+
return typeof type === "function" && "__setup" in type;
|
|
308
301
|
}
|
|
309
|
-
|
|
310
|
-
//#endregion
|
|
311
|
-
//#region src/jsx-runtime.ts
|
|
312
302
|
const Fragment = Symbol.for("sigx.Fragment");
|
|
313
303
|
const Text = Symbol.for("sigx.Text");
|
|
314
304
|
function normalizeChildren(children) {
|
|
315
305
|
if (children == null || children === false || children === true) return [];
|
|
306
|
+
if (isComputed(children)) return normalizeChildren(children.value);
|
|
316
307
|
if (Array.isArray(children)) return children.flatMap((c) => normalizeChildren(c));
|
|
317
308
|
if (typeof children === "string" || typeof children === "number") return [{
|
|
318
309
|
type: Text,
|
|
@@ -325,64 +316,92 @@ function normalizeChildren(children) {
|
|
|
325
316
|
if (children.type) return [children];
|
|
326
317
|
return [];
|
|
327
318
|
}
|
|
328
|
-
/**
|
|
329
|
-
* Check if a type is a sigx component (has __setup)
|
|
330
|
-
*/
|
|
331
|
-
function isComponent$1(type) {
|
|
332
|
-
return typeof type === "function" && "__setup" in type;
|
|
333
|
-
}
|
|
334
|
-
/**
|
|
335
|
-
* Create a JSX element - this is the core function called by TSX transpilation
|
|
336
|
-
*/
|
|
337
319
|
function jsx(type, props, key) {
|
|
338
320
|
const processedProps = { ...props || {} };
|
|
321
|
+
const models = {};
|
|
322
|
+
const isComponentType = isComponent(type);
|
|
339
323
|
if (props) {
|
|
340
|
-
for (const propKey in props) if (propKey === "
|
|
341
|
-
let
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
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;
|
|
348
338
|
let handled = false;
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
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;
|
|
356
345
|
if (existingHandler) existingHandler(v);
|
|
357
346
|
};
|
|
358
347
|
}
|
|
359
|
-
|
|
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;
|
|
360
358
|
}
|
|
361
|
-
} else if (propKey.startsWith("
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
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;
|
|
367
374
|
const eventName = `onUpdate:${name}`;
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
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
|
+
}
|
|
373
391
|
delete processedProps[propKey];
|
|
374
392
|
}
|
|
375
393
|
}
|
|
376
394
|
}
|
|
377
|
-
if (
|
|
378
|
-
|
|
395
|
+
if (Object.keys(models).length > 0) processedProps.$models = models;
|
|
396
|
+
if (isComponent(type)) {
|
|
397
|
+
const { children, ...rest } = processedProps;
|
|
379
398
|
return {
|
|
380
399
|
type,
|
|
381
400
|
props: {
|
|
382
|
-
...rest
|
|
383
|
-
children
|
|
401
|
+
...rest,
|
|
402
|
+
children
|
|
384
403
|
},
|
|
385
|
-
key: key || rest
|
|
404
|
+
key: key || rest.key || null,
|
|
386
405
|
children: [],
|
|
387
406
|
dom: null
|
|
388
407
|
};
|
|
@@ -397,27 +416,11 @@ function jsx(type, props, key) {
|
|
|
397
416
|
dom: null
|
|
398
417
|
};
|
|
399
418
|
}
|
|
400
|
-
/**
|
|
401
|
-
* JSX Factory for fragments
|
|
402
|
-
*/
|
|
403
419
|
function jsxs(type, props, key) {
|
|
404
420
|
return jsx(type, props, key);
|
|
405
421
|
}
|
|
406
422
|
const jsxDEV = jsx;
|
|
407
|
-
|
|
408
|
-
//#endregion
|
|
409
|
-
//#region src/lazy.tsx
|
|
410
|
-
/**
|
|
411
|
-
* Lazy loading utilities for sigx components.
|
|
412
|
-
*
|
|
413
|
-
* Provides runtime-only lazy loading with no build dependencies.
|
|
414
|
-
* Works with any bundler that supports dynamic import().
|
|
415
|
-
*/
|
|
416
|
-
let currentSuspenseBoundary = null;
|
|
417
|
-
/**
|
|
418
|
-
* Register a promise with the current Suspense boundary
|
|
419
|
-
* @internal
|
|
420
|
-
*/
|
|
423
|
+
var currentSuspenseBoundary = null;
|
|
421
424
|
function registerPendingPromise(promise) {
|
|
422
425
|
const boundary = currentSuspenseBoundary;
|
|
423
426
|
if (boundary) {
|
|
@@ -430,39 +433,12 @@ function registerPendingPromise(promise) {
|
|
|
430
433
|
}
|
|
431
434
|
return false;
|
|
432
435
|
}
|
|
433
|
-
/**
|
|
434
|
-
* Create a lazy-loaded component wrapper.
|
|
435
|
-
*
|
|
436
|
-
* The component will be loaded on first render. Use with `<Suspense>` to show
|
|
437
|
-
* a fallback while loading.
|
|
438
|
-
*
|
|
439
|
-
* @param loader - Function that returns a Promise resolving to the component
|
|
440
|
-
* @returns A component factory that loads the real component on demand
|
|
441
|
-
*
|
|
442
|
-
* @example
|
|
443
|
-
* ```tsx
|
|
444
|
-
* import { lazy, Suspense } from 'sigx';
|
|
445
|
-
*
|
|
446
|
-
* // Component will be in a separate chunk
|
|
447
|
-
* const HeavyChart = lazy(() => import('./components/HeavyChart'));
|
|
448
|
-
*
|
|
449
|
-
* // Usage
|
|
450
|
-
* <Suspense fallback={<Spinner />}>
|
|
451
|
-
* <HeavyChart data={chartData} />
|
|
452
|
-
* </Suspense>
|
|
453
|
-
*
|
|
454
|
-
* // Preload on hover
|
|
455
|
-
* <button onMouseEnter={() => HeavyChart.preload()}>
|
|
456
|
-
* Show Chart
|
|
457
|
-
* </button>
|
|
458
|
-
* ```
|
|
459
|
-
*/
|
|
460
436
|
function lazy(loader) {
|
|
461
437
|
let Component = null;
|
|
462
438
|
let promise = null;
|
|
463
439
|
let error = null;
|
|
464
440
|
let state = "pending";
|
|
465
|
-
const LazyWrapper =
|
|
441
|
+
const LazyWrapper = component((ctx) => {
|
|
466
442
|
const loadState = ctx.signal({
|
|
467
443
|
state,
|
|
468
444
|
tick: 0
|
|
@@ -511,30 +487,7 @@ function lazy(loader) {
|
|
|
511
487
|
};
|
|
512
488
|
return LazyWrapper;
|
|
513
489
|
}
|
|
514
|
-
|
|
515
|
-
* Suspense boundary component for handling async loading states.
|
|
516
|
-
*
|
|
517
|
-
* Wraps lazy-loaded components and shows a fallback while they load.
|
|
518
|
-
*
|
|
519
|
-
* @example
|
|
520
|
-
* ```tsx
|
|
521
|
-
* import { lazy, Suspense } from 'sigx';
|
|
522
|
-
*
|
|
523
|
-
* const LazyDashboard = lazy(() => import('./Dashboard'));
|
|
524
|
-
*
|
|
525
|
-
* // Basic usage
|
|
526
|
-
* <Suspense fallback={<div>Loading...</div>}>
|
|
527
|
-
* <LazyDashboard />
|
|
528
|
-
* </Suspense>
|
|
529
|
-
*
|
|
530
|
-
* // With spinner component
|
|
531
|
-
* <Suspense fallback={<Spinner size="large" />}>
|
|
532
|
-
* <LazyDashboard />
|
|
533
|
-
* <LazyCharts />
|
|
534
|
-
* </Suspense>
|
|
535
|
-
* ```
|
|
536
|
-
*/
|
|
537
|
-
const Suspense = defineComponent((ctx) => {
|
|
490
|
+
const Suspense = component((ctx) => {
|
|
538
491
|
const { props, slots } = ctx;
|
|
539
492
|
const state = ctx.signal({
|
|
540
493
|
isReady: false,
|
|
@@ -547,7 +500,7 @@ const Suspense = defineComponent((ctx) => {
|
|
|
547
500
|
if (boundary.pending.size === 0) state.isReady = true;
|
|
548
501
|
}
|
|
549
502
|
};
|
|
550
|
-
ctx.
|
|
503
|
+
ctx.onMounted(() => {
|
|
551
504
|
if (boundary.pending.size === 0) state.isReady = true;
|
|
552
505
|
});
|
|
553
506
|
return () => {
|
|
@@ -582,15 +535,9 @@ const Suspense = defineComponent((ctx) => {
|
|
|
582
535
|
}
|
|
583
536
|
};
|
|
584
537
|
}, { name: "Suspense" });
|
|
585
|
-
/**
|
|
586
|
-
* Check if a component is a lazy-loaded component
|
|
587
|
-
*/
|
|
588
538
|
function isLazyComponent(component) {
|
|
589
539
|
return component && component.__lazy === true;
|
|
590
540
|
}
|
|
591
|
-
|
|
592
|
-
//#endregion
|
|
593
|
-
//#region src/utils/index.ts
|
|
594
541
|
var Utils = class {
|
|
595
542
|
static isPromise(value) {
|
|
596
543
|
return !!value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
|
|
@@ -602,22 +549,112 @@ function guid$1() {
|
|
|
602
549
|
return (c == "x" ? r : r & 3 | 8).toString(16);
|
|
603
550
|
});
|
|
604
551
|
}
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
552
|
+
function createPropsAccessor(reactiveProps) {
|
|
553
|
+
return new Proxy(reactiveProps, {
|
|
554
|
+
get(target, key) {
|
|
555
|
+
if (typeof key === "symbol") return void 0;
|
|
556
|
+
return target[key];
|
|
557
|
+
},
|
|
558
|
+
has(target, key) {
|
|
559
|
+
if (typeof key === "symbol") return false;
|
|
560
|
+
return key in target;
|
|
561
|
+
},
|
|
562
|
+
ownKeys(target) {
|
|
563
|
+
return Object.keys(target);
|
|
564
|
+
},
|
|
565
|
+
getOwnPropertyDescriptor(target, key) {
|
|
566
|
+
if (typeof key === "symbol") return void 0;
|
|
567
|
+
if (key in target) return {
|
|
568
|
+
enumerable: true,
|
|
569
|
+
configurable: true,
|
|
570
|
+
writable: false
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
function createSlots(children, slotsFromProps) {
|
|
576
|
+
const versionSignal = signal$1({ v: 0 });
|
|
577
|
+
function extractNamedSlotsFromChildren(c) {
|
|
578
|
+
const defaultChildren = [];
|
|
579
|
+
const namedSlots = {};
|
|
580
|
+
if (c == null) return {
|
|
581
|
+
defaultChildren,
|
|
582
|
+
namedSlots
|
|
583
|
+
};
|
|
584
|
+
const items = Array.isArray(c) ? c : [c];
|
|
585
|
+
for (const child of items) if (child && typeof child === "object" && child.props && child.props.slot) {
|
|
586
|
+
const slotName = child.props.slot;
|
|
587
|
+
if (!namedSlots[slotName]) namedSlots[slotName] = [];
|
|
588
|
+
namedSlots[slotName].push(child);
|
|
589
|
+
} else defaultChildren.push(child);
|
|
590
|
+
return {
|
|
591
|
+
defaultChildren,
|
|
592
|
+
namedSlots
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
const slotsObj = {
|
|
596
|
+
_children: children,
|
|
597
|
+
_slotsFromProps: slotsFromProps || {},
|
|
598
|
+
_version: versionSignal,
|
|
599
|
+
_isPatching: false,
|
|
600
|
+
default: function() {
|
|
601
|
+
this._version.v;
|
|
602
|
+
const c = this._children;
|
|
603
|
+
const { defaultChildren } = extractNamedSlotsFromChildren(c);
|
|
604
|
+
return defaultChildren.filter((child) => child != null && child !== false && child !== true);
|
|
605
|
+
}
|
|
606
|
+
};
|
|
607
|
+
return new Proxy(slotsObj, { get(target, prop) {
|
|
608
|
+
if (prop in target) return target[prop];
|
|
609
|
+
if (typeof prop === "string") return function(scopedProps) {
|
|
610
|
+
target._version.v;
|
|
611
|
+
if (target._slotsFromProps && typeof target._slotsFromProps[prop] === "function") {
|
|
612
|
+
const result = target._slotsFromProps[prop](scopedProps);
|
|
613
|
+
if (result == null) return [];
|
|
614
|
+
return Array.isArray(result) ? result : [result];
|
|
615
|
+
}
|
|
616
|
+
const { namedSlots } = extractNamedSlotsFromChildren(target._children);
|
|
617
|
+
return namedSlots[prop] || [];
|
|
618
|
+
};
|
|
619
|
+
} });
|
|
620
|
+
}
|
|
621
|
+
function normalizeSubTree(result) {
|
|
622
|
+
if (result == null || result === false || result === true) return {
|
|
623
|
+
type: Text,
|
|
624
|
+
props: {},
|
|
625
|
+
key: null,
|
|
626
|
+
children: [],
|
|
627
|
+
dom: null,
|
|
628
|
+
text: ""
|
|
629
|
+
};
|
|
630
|
+
if (isComputed(result)) return normalizeSubTree(result.value);
|
|
631
|
+
if (Array.isArray(result)) return {
|
|
632
|
+
type: Fragment,
|
|
633
|
+
props: {},
|
|
634
|
+
key: null,
|
|
635
|
+
children: result,
|
|
636
|
+
dom: null
|
|
637
|
+
};
|
|
638
|
+
if (typeof result === "string" || typeof result === "number") return {
|
|
639
|
+
type: Text,
|
|
640
|
+
props: {},
|
|
641
|
+
key: null,
|
|
642
|
+
children: [],
|
|
643
|
+
dom: null,
|
|
644
|
+
text: result
|
|
645
|
+
};
|
|
646
|
+
return result;
|
|
647
|
+
}
|
|
608
648
|
const guid = guid$1;
|
|
609
|
-
let InstanceLifetimes = /* @__PURE__ */ function(InstanceLifetimes
|
|
610
|
-
InstanceLifetimes
|
|
611
|
-
InstanceLifetimes
|
|
612
|
-
InstanceLifetimes
|
|
613
|
-
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;
|
|
614
654
|
}({});
|
|
615
655
|
function valueOf(obj) {
|
|
616
656
|
return obj;
|
|
617
657
|
}
|
|
618
|
-
|
|
619
|
-
//#endregion
|
|
620
|
-
//#region src/messaging/index.ts
|
|
621
658
|
function createTopic(options) {
|
|
622
659
|
let subscribers = [];
|
|
623
660
|
const publish = (data) => {
|
|
@@ -630,7 +667,7 @@ function createTopic(options) {
|
|
|
630
667
|
if (idx > -1) subscribers.splice(idx, 1);
|
|
631
668
|
};
|
|
632
669
|
try {
|
|
633
|
-
|
|
670
|
+
onUnmounted(unsubscribe);
|
|
634
671
|
} catch (e) {}
|
|
635
672
|
return { unsubscribe };
|
|
636
673
|
};
|
|
@@ -646,72 +683,10 @@ function createTopic(options) {
|
|
|
646
683
|
function toSubscriber(topic) {
|
|
647
684
|
return { subscribe: (handler) => topic.subscribe(handler) };
|
|
648
685
|
}
|
|
649
|
-
|
|
650
|
-
//#endregion
|
|
651
|
-
//#region src/di/injectable.ts
|
|
652
|
-
function inject(token) {
|
|
653
|
-
const ctx = getCurrentInstance();
|
|
654
|
-
if (!ctx) return void 0;
|
|
655
|
-
let current = ctx;
|
|
656
|
-
while (current) {
|
|
657
|
-
if (current.provides && current.provides.has(token)) return current.provides.get(token);
|
|
658
|
-
current = current.parent;
|
|
659
|
-
}
|
|
660
|
-
const appContext = getAppContext(ctx);
|
|
661
|
-
if (appContext && appContext.provides.has(token)) return appContext.provides.get(token);
|
|
662
|
-
}
|
|
663
|
-
/**
|
|
664
|
-
* Get the app context from the current component context
|
|
665
|
-
*/
|
|
666
|
-
function getAppContext(ctx) {
|
|
667
|
-
let current = ctx;
|
|
668
|
-
while (current) {
|
|
669
|
-
if (current._appContext) return current._appContext;
|
|
670
|
-
current = current.parent;
|
|
671
|
-
}
|
|
672
|
-
return null;
|
|
673
|
-
}
|
|
674
|
-
/**
|
|
675
|
-
* Inject the App instance (useful for plugins)
|
|
676
|
-
*/
|
|
677
|
-
function injectApp() {
|
|
678
|
-
return inject(AppContextKey);
|
|
679
|
-
}
|
|
680
|
-
function provide(token, value) {
|
|
681
|
-
const ctx = getCurrentInstance();
|
|
682
|
-
if (!ctx) {
|
|
683
|
-
console.warn("provide called outside of component setup");
|
|
684
|
-
return;
|
|
685
|
-
}
|
|
686
|
-
if (!ctx.provides) ctx.provides = /* @__PURE__ */ new Map();
|
|
687
|
-
ctx.provides.set(token, value);
|
|
688
|
-
}
|
|
689
|
-
const globalInstances = /* @__PURE__ */ new Map();
|
|
690
|
-
function defineInjectable(factory) {
|
|
691
|
-
const token = factory;
|
|
692
|
-
const useFn = () => {
|
|
693
|
-
const injected = inject(token);
|
|
694
|
-
if (injected) return injected;
|
|
695
|
-
if (!globalInstances.has(token)) globalInstances.set(token, factory());
|
|
696
|
-
return globalInstances.get(token);
|
|
697
|
-
};
|
|
698
|
-
useFn._factory = factory;
|
|
699
|
-
useFn._token = token;
|
|
700
|
-
return useFn;
|
|
701
|
-
}
|
|
702
|
-
function defineProvide(useFn) {
|
|
703
|
-
const factory = useFn._factory;
|
|
704
|
-
const token = useFn._token;
|
|
705
|
-
if (!factory || !token) throw new Error("defineProvide must be called with a function created by defineInjectable");
|
|
706
|
-
const instance = factory();
|
|
707
|
-
provide(token, instance);
|
|
708
|
-
return instance;
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
//#endregion
|
|
712
|
-
//#region src/di/factory.ts
|
|
713
686
|
var SubscriptionHandler = class {
|
|
714
|
-
|
|
687
|
+
constructor() {
|
|
688
|
+
this.unsubs = [];
|
|
689
|
+
}
|
|
715
690
|
add(unsub) {
|
|
716
691
|
this.unsubs.push(unsub);
|
|
717
692
|
}
|
|
@@ -737,7 +712,7 @@ function defineFactory(setup, lifetime, typeIdentifier) {
|
|
|
737
712
|
};
|
|
738
713
|
if (customDispose) customDispose(dispose);
|
|
739
714
|
else try {
|
|
740
|
-
|
|
715
|
+
onUnmounted(() => dispose());
|
|
741
716
|
} catch (e) {}
|
|
742
717
|
return {
|
|
743
718
|
...result,
|
|
@@ -747,155 +722,59 @@ function defineFactory(setup, lifetime, typeIdentifier) {
|
|
|
747
722
|
if (setup.length <= 1) return defineInjectable(() => factoryCreator());
|
|
748
723
|
return factoryCreator;
|
|
749
724
|
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
},
|
|
763
|
-
defineActions: (actions) => {
|
|
764
|
-
return defineActions(actions, id, messages);
|
|
765
|
-
}
|
|
766
|
-
}, ...args);
|
|
767
|
-
ctxFactory.onDeactivated(() => {
|
|
768
|
-
scope.stop();
|
|
769
|
-
messages?.forEach((m) => m.destroy());
|
|
770
|
-
messages = null;
|
|
771
|
-
});
|
|
772
|
-
if (!result.name) result.name = id;
|
|
773
|
-
return result;
|
|
774
|
-
}, 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;
|
|
775
737
|
}
|
|
776
|
-
function
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
onDispatched,
|
|
785
|
-
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"]
|
|
786
746
|
};
|
|
787
|
-
|
|
788
|
-
const name = `${actionName}.${type}`;
|
|
789
|
-
if (!events[name]) {
|
|
790
|
-
events[name] = createTopic({
|
|
791
|
-
namespace,
|
|
792
|
-
name
|
|
793
|
-
});
|
|
794
|
-
messages.push(events[name]);
|
|
795
|
-
}
|
|
796
|
-
return events[name];
|
|
797
|
-
}
|
|
798
|
-
Object.keys(actions).forEach((actionName) => {
|
|
799
|
-
onDispatching[actionName] = { subscribe: (fn) => {
|
|
800
|
-
return getEvent(actionName, "onDispatching").subscribe(function() {
|
|
801
|
-
fn.apply(this, arguments[0]);
|
|
802
|
-
});
|
|
803
|
-
} };
|
|
804
|
-
onDispatched[actionName] = { subscribe: (fn) => {
|
|
805
|
-
return getEvent(actionName, "onDispatched").subscribe(function() {
|
|
806
|
-
const msg = arguments[0];
|
|
807
|
-
const allArguments = [msg.result].concat(Array.from(msg.args));
|
|
808
|
-
fn.apply(this, allArguments);
|
|
809
|
-
});
|
|
810
|
-
} };
|
|
811
|
-
onFailure[actionName] = { subscribe: (fn) => {
|
|
812
|
-
return getEvent(actionName, "onFailure").subscribe(function() {
|
|
813
|
-
const msg = arguments[0];
|
|
814
|
-
const allArguments = [msg.reason].concat(Array.from(msg.args));
|
|
815
|
-
fn.apply(this, allArguments);
|
|
816
|
-
});
|
|
817
|
-
} };
|
|
818
|
-
result[actionName] = function() {
|
|
819
|
-
try {
|
|
820
|
-
const currentArguments = arguments;
|
|
821
|
-
getEvent(actionName, "onDispatching").publish(currentArguments);
|
|
822
|
-
const returnedResult = actions[actionName].apply(this, currentArguments);
|
|
823
|
-
if (Utils.isPromise(returnedResult)) returnedResult.then((result$1) => {
|
|
824
|
-
getEvent(actionName, "onDispatched").publish({
|
|
825
|
-
result: returnedResult,
|
|
826
|
-
args: currentArguments
|
|
827
|
-
});
|
|
828
|
-
});
|
|
829
|
-
else getEvent(actionName, "onDispatched").publish({
|
|
830
|
-
result: returnedResult,
|
|
831
|
-
args: currentArguments
|
|
832
|
-
});
|
|
833
|
-
return returnedResult;
|
|
834
|
-
} catch (err) {
|
|
835
|
-
console.error(err);
|
|
836
|
-
getEvent(actionName, "onFailure").publish({
|
|
837
|
-
reason: err,
|
|
838
|
-
args: arguments
|
|
839
|
-
});
|
|
840
|
-
}
|
|
841
|
-
};
|
|
842
|
-
});
|
|
843
|
-
return result;
|
|
747
|
+
return null;
|
|
844
748
|
}
|
|
845
|
-
function
|
|
846
|
-
const
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
console.error(err);
|
|
866
|
-
}
|
|
867
|
-
};
|
|
868
|
-
const eventKey = `onMutated${key.charAt(0).toUpperCase()}${key.slice(1)}`;
|
|
869
|
-
if (!events[eventKey]) {
|
|
870
|
-
const topic = createTopic({
|
|
871
|
-
namespace: `${storeInstanceName}.events`,
|
|
872
|
-
name: eventKey
|
|
873
|
-
});
|
|
874
|
-
events[eventKey] = topic;
|
|
875
|
-
messages.push(topic);
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
function triggerEvent(name, value$1) {
|
|
879
|
-
const keyString = name;
|
|
880
|
-
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 {}
|
|
881
769
|
}
|
|
882
|
-
|
|
883
|
-
initProperty(key);
|
|
884
|
-
});
|
|
885
|
-
return {
|
|
886
|
-
state,
|
|
887
|
-
events,
|
|
888
|
-
mutate
|
|
889
|
-
};
|
|
770
|
+
return hasProps ? result : void 0;
|
|
890
771
|
}
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
function isComponent(type) {
|
|
898
|
-
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
|
+
};
|
|
899
778
|
}
|
|
900
779
|
function createRenderer(options) {
|
|
901
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;
|
|
@@ -929,7 +808,72 @@ function createRenderer(options) {
|
|
|
929
808
|
container._vnode = null;
|
|
930
809
|
}
|
|
931
810
|
}
|
|
932
|
-
|
|
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) {
|
|
933
877
|
if (vnode == null || vnode === false || vnode === true) return;
|
|
934
878
|
if (vnode.type === Text) {
|
|
935
879
|
const node = hostCreateText(String(vnode.text));
|
|
@@ -942,26 +886,29 @@ function createRenderer(options) {
|
|
|
942
886
|
const anchor = hostCreateComment("");
|
|
943
887
|
vnode.dom = anchor;
|
|
944
888
|
hostInsert(anchor, container, before);
|
|
945
|
-
if (vnode.children) vnode.children.forEach((child) => mount(child, container, anchor));
|
|
889
|
+
if (vnode.children) vnode.children.forEach((child) => mount(child, container, anchor, parentIsSVG));
|
|
946
890
|
return;
|
|
947
891
|
}
|
|
948
892
|
if (isComponent(vnode.type)) {
|
|
949
893
|
mountComponent(vnode, container, before, vnode.type.__setup);
|
|
950
894
|
return;
|
|
951
895
|
}
|
|
952
|
-
const
|
|
896
|
+
const tag = vnode.type;
|
|
897
|
+
const isSVG = tag === "svg" || parentIsSVG && tag !== "foreignObject";
|
|
898
|
+
const element = hostCreateElement(tag, isSVG);
|
|
953
899
|
vnode.dom = element;
|
|
954
900
|
element.__vnode = vnode;
|
|
955
901
|
if (vnode.props) {
|
|
956
|
-
for (const key in vnode.props) if (key !== "children" && key !== "key" && key !== "ref") hostPatchProp(element, key, null, vnode.props[key]);
|
|
957
|
-
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(() => {
|
|
958
904
|
if (typeof vnode.props.ref === "function") vnode.props.ref(element);
|
|
959
905
|
else if (typeof vnode.props.ref === "object") vnode.props.ref.current = element;
|
|
960
|
-
}
|
|
906
|
+
});
|
|
961
907
|
}
|
|
908
|
+
const childIsSVG = isSVG && tag !== "foreignObject";
|
|
962
909
|
if (vnode.children) vnode.children.forEach((child) => {
|
|
963
910
|
child.parent = vnode;
|
|
964
|
-
mount(child, element);
|
|
911
|
+
mount(child, element, null, childIsSVG);
|
|
965
912
|
});
|
|
966
913
|
hostInsert(element, container, before);
|
|
967
914
|
}
|
|
@@ -973,10 +920,10 @@ function createRenderer(options) {
|
|
|
973
920
|
const subTree = internalVNode._subTree;
|
|
974
921
|
if (subTree) unmount(subTree, container);
|
|
975
922
|
if (vnode.dom) hostRemove(vnode.dom);
|
|
976
|
-
if (vnode.props?.ref) {
|
|
923
|
+
if (vnode.props?.ref) untrack(() => {
|
|
977
924
|
if (typeof vnode.props.ref === "function") vnode.props.ref(null);
|
|
978
925
|
else if (typeof vnode.props.ref === "object") vnode.props.ref.current = null;
|
|
979
|
-
}
|
|
926
|
+
});
|
|
980
927
|
return;
|
|
981
928
|
}
|
|
982
929
|
if (vnode.type === Fragment) {
|
|
@@ -984,10 +931,10 @@ function createRenderer(options) {
|
|
|
984
931
|
if (vnode.dom) hostRemove(vnode.dom);
|
|
985
932
|
return;
|
|
986
933
|
}
|
|
987
|
-
if (vnode.props?.ref) {
|
|
934
|
+
if (vnode.props?.ref) untrack(() => {
|
|
988
935
|
if (typeof vnode.props.ref === "function") vnode.props.ref(null);
|
|
989
936
|
else if (vnode.props.ref && typeof vnode.props.ref === "object") vnode.props.ref.current = null;
|
|
990
|
-
}
|
|
937
|
+
});
|
|
991
938
|
if (vnode.children && vnode.children.length > 0) vnode.children.forEach((child) => unmount(child, vnode.dom));
|
|
992
939
|
if (vnode.dom) hostRemove(vnode.dom);
|
|
993
940
|
}
|
|
@@ -995,7 +942,7 @@ function createRenderer(options) {
|
|
|
995
942
|
if (oldVNode === newVNode) return;
|
|
996
943
|
if (!isSameVNode(oldVNode, newVNode)) {
|
|
997
944
|
const parent = hostParentNode(oldVNode.dom) || container;
|
|
998
|
-
const nextSibling = hostNextSibling(oldVNode.dom);
|
|
945
|
+
const nextSibling = oldVNode.dom ? hostNextSibling(oldVNode.dom) : null;
|
|
999
946
|
unmount(oldVNode, parent);
|
|
1000
947
|
mount(newVNode, parent, nextSibling);
|
|
1001
948
|
return;
|
|
@@ -1010,12 +957,25 @@ function createRenderer(options) {
|
|
|
1010
957
|
const props = oldInternal._componentProps;
|
|
1011
958
|
newInternal._componentProps = props;
|
|
1012
959
|
if (props) {
|
|
1013
|
-
const newProps
|
|
960
|
+
const newProps = newVNode.props || {};
|
|
961
|
+
const newModels = newVNode.props?.$models || {};
|
|
1014
962
|
untrack(() => {
|
|
1015
|
-
for (const key in newProps
|
|
1016
|
-
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];
|
|
1017
965
|
}
|
|
1018
|
-
for (const
|
|
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
|
+
}
|
|
977
|
+
}
|
|
978
|
+
for (const key in props) if (!(key in newProps) && !(key in newModels) && key !== "children" && key !== "key" && key !== "ref" && key !== "$models") delete props[key];
|
|
1019
979
|
});
|
|
1020
980
|
}
|
|
1021
981
|
const slotsRef = oldInternal._slots;
|
|
@@ -1043,27 +1003,43 @@ function createRenderer(options) {
|
|
|
1043
1003
|
return;
|
|
1044
1004
|
}
|
|
1045
1005
|
if (newVNode.type === Fragment) {
|
|
1046
|
-
patchChildren(oldVNode, newVNode, container);
|
|
1006
|
+
patchChildren(oldVNode, newVNode, container, false);
|
|
1047
1007
|
return;
|
|
1048
1008
|
}
|
|
1049
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);
|
|
1050
1016
|
const oldProps = oldVNode.props || {};
|
|
1051
1017
|
const newProps = newVNode.props || {};
|
|
1052
|
-
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);
|
|
1053
1019
|
for (const key in newProps) {
|
|
1054
1020
|
const oldValue = oldProps[key];
|
|
1055
1021
|
const newValue = newProps[key];
|
|
1056
|
-
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);
|
|
1057
1023
|
}
|
|
1058
|
-
patchChildren(oldVNode, newVNode, element);
|
|
1024
|
+
patchChildren(oldVNode, newVNode, element, isSVG && tag !== "foreignObject");
|
|
1059
1025
|
}
|
|
1060
|
-
function patchChildren(oldVNode, newVNode, container) {
|
|
1026
|
+
function patchChildren(oldVNode, newVNode, container, parentIsSVG = false) {
|
|
1061
1027
|
const oldChildren = oldVNode.children;
|
|
1062
1028
|
const newChildren = newVNode.children;
|
|
1063
1029
|
newChildren.forEach((c) => c.parent = newVNode);
|
|
1064
|
-
reconcileChildrenArray(container, oldChildren, newChildren);
|
|
1030
|
+
reconcileChildrenArray(container, oldChildren, newChildren, parentIsSVG);
|
|
1065
1031
|
}
|
|
1066
|
-
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);
|
|
1067
1043
|
let oldStartIdx = 0;
|
|
1068
1044
|
let oldEndIdx = oldChildren.length - 1;
|
|
1069
1045
|
let oldStartVNode = oldChildren[0];
|
|
@@ -1105,13 +1081,13 @@ function createRenderer(options) {
|
|
|
1105
1081
|
patch(vnodeToMove, newStartVNode, parent);
|
|
1106
1082
|
oldChildren[idxInOld] = void 0;
|
|
1107
1083
|
if (vnodeToMove.dom && oldStartVNode.dom) hostInsert(vnodeToMove.dom, parent, oldStartVNode.dom);
|
|
1108
|
-
} else mount(newStartVNode, parent, oldStartVNode.dom);
|
|
1084
|
+
} else mount(newStartVNode, parent, oldStartVNode.dom, parentIsSVG);
|
|
1109
1085
|
newStartVNode = newChildren[++newStartIdx];
|
|
1110
1086
|
}
|
|
1111
1087
|
if (oldStartIdx > oldEndIdx) {
|
|
1112
1088
|
if (newStartIdx <= newEndIdx) {
|
|
1113
1089
|
const anchor = newChildren[newEndIdx + 1] == null ? null : newChildren[newEndIdx + 1].dom;
|
|
1114
|
-
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);
|
|
1115
1091
|
}
|
|
1116
1092
|
} else if (newStartIdx > newEndIdx) {
|
|
1117
1093
|
for (let i = oldStartIdx; i <= oldEndIdx; i++) if (oldChildren[i]) unmount(oldChildren[i], parent);
|
|
@@ -1128,7 +1104,11 @@ function createRenderer(options) {
|
|
|
1128
1104
|
const map = /* @__PURE__ */ new Map();
|
|
1129
1105
|
for (let i = beginIdx; i <= endIdx; i++) {
|
|
1130
1106
|
const key = children[i]?.key;
|
|
1131
|
-
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
|
+
}
|
|
1132
1112
|
}
|
|
1133
1113
|
return map;
|
|
1134
1114
|
}
|
|
@@ -1136,43 +1116,6 @@ function createRenderer(options) {
|
|
|
1136
1116
|
for (let i = beginIdx; i <= endIdx; i++) if (children[i] && isSameVNode(children[i], newChild)) return i;
|
|
1137
1117
|
return null;
|
|
1138
1118
|
}
|
|
1139
|
-
/**
|
|
1140
|
-
* Creates a props accessor that can be called with defaults or accessed directly.
|
|
1141
|
-
* After calling with defaults, direct property access uses those defaults.
|
|
1142
|
-
*/
|
|
1143
|
-
function createPropsAccessor(reactiveProps) {
|
|
1144
|
-
let defaults = {};
|
|
1145
|
-
const proxy = new Proxy(function propsAccessor() {}, {
|
|
1146
|
-
get(_, key) {
|
|
1147
|
-
if (typeof key === "symbol") return void 0;
|
|
1148
|
-
const value = reactiveProps[key];
|
|
1149
|
-
return value != null ? value : defaults[key];
|
|
1150
|
-
},
|
|
1151
|
-
apply(_, __, args) {
|
|
1152
|
-
if (args[0] && typeof args[0] === "object") defaults = {
|
|
1153
|
-
...defaults,
|
|
1154
|
-
...args[0]
|
|
1155
|
-
};
|
|
1156
|
-
return proxy;
|
|
1157
|
-
},
|
|
1158
|
-
has(_, key) {
|
|
1159
|
-
if (typeof key === "symbol") return false;
|
|
1160
|
-
return key in reactiveProps || key in defaults;
|
|
1161
|
-
},
|
|
1162
|
-
ownKeys() {
|
|
1163
|
-
return [...new Set([...Object.keys(reactiveProps), ...Object.keys(defaults)])];
|
|
1164
|
-
},
|
|
1165
|
-
getOwnPropertyDescriptor(_, key) {
|
|
1166
|
-
if (typeof key === "symbol") return void 0;
|
|
1167
|
-
if (key in reactiveProps || key in defaults) return {
|
|
1168
|
-
enumerable: true,
|
|
1169
|
-
configurable: true,
|
|
1170
|
-
writable: false
|
|
1171
|
-
};
|
|
1172
|
-
}
|
|
1173
|
-
});
|
|
1174
|
-
return proxy;
|
|
1175
|
-
}
|
|
1176
1119
|
function mountComponent(vnode, container, before, setup) {
|
|
1177
1120
|
const anchor = hostCreateComment("");
|
|
1178
1121
|
vnode.dom = anchor;
|
|
@@ -1180,14 +1123,21 @@ function createRenderer(options) {
|
|
|
1180
1123
|
hostInsert(anchor, container, before);
|
|
1181
1124
|
let exposed = null;
|
|
1182
1125
|
let exposeCalled = false;
|
|
1183
|
-
const { children, slots: slotsFromProps, ...propsData } = vnode.props || {};
|
|
1184
|
-
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);
|
|
1185
1133
|
const internalVNode = vnode;
|
|
1186
1134
|
internalVNode._componentProps = reactiveProps;
|
|
1187
1135
|
const slots = createSlots(children, slotsFromProps);
|
|
1188
1136
|
internalVNode._slots = slots;
|
|
1137
|
+
const createdHooks = [];
|
|
1189
1138
|
const mountHooks = [];
|
|
1190
|
-
const
|
|
1139
|
+
const updatedHooks = [];
|
|
1140
|
+
const unmountHooks = [];
|
|
1191
1141
|
const parentInstance = getCurrentInstance();
|
|
1192
1142
|
const componentName = vnode.type.__name;
|
|
1193
1143
|
const ctx = {
|
|
@@ -1195,16 +1145,19 @@ function createRenderer(options) {
|
|
|
1195
1145
|
signal: signal$1,
|
|
1196
1146
|
props: createPropsAccessor(reactiveProps),
|
|
1197
1147
|
slots,
|
|
1198
|
-
emit: (
|
|
1199
|
-
const handler = reactiveProps[`on${event[0].toUpperCase() + event.slice(1)}`];
|
|
1200
|
-
if (handler && typeof handler === "function") handler(...args);
|
|
1201
|
-
},
|
|
1148
|
+
emit: createEmit(reactiveProps),
|
|
1202
1149
|
parent: parentInstance,
|
|
1203
|
-
|
|
1150
|
+
onMounted: (fn) => {
|
|
1204
1151
|
mountHooks.push(fn);
|
|
1205
1152
|
},
|
|
1206
|
-
|
|
1207
|
-
|
|
1153
|
+
onUnmounted: (fn) => {
|
|
1154
|
+
unmountHooks.push(fn);
|
|
1155
|
+
},
|
|
1156
|
+
onCreated: (fn) => {
|
|
1157
|
+
createdHooks.push(fn);
|
|
1158
|
+
},
|
|
1159
|
+
onUpdated: (fn) => {
|
|
1160
|
+
updatedHooks.push(fn);
|
|
1208
1161
|
},
|
|
1209
1162
|
expose: (exposedValue) => {
|
|
1210
1163
|
exposed = exposedValue;
|
|
@@ -1213,8 +1166,9 @@ function createRenderer(options) {
|
|
|
1213
1166
|
renderFn: null,
|
|
1214
1167
|
update: () => {}
|
|
1215
1168
|
};
|
|
1169
|
+
applyContextExtensions(ctx);
|
|
1216
1170
|
ctx.__name = componentName;
|
|
1217
|
-
if (currentAppContext) ctx
|
|
1171
|
+
if (!parentInstance && currentAppContext) provideAppContext(ctx, currentAppContext);
|
|
1218
1172
|
const componentInstance = {
|
|
1219
1173
|
name: componentName,
|
|
1220
1174
|
ctx,
|
|
@@ -1223,8 +1177,11 @@ function createRenderer(options) {
|
|
|
1223
1177
|
const prev = setCurrentInstance(ctx);
|
|
1224
1178
|
let renderFn;
|
|
1225
1179
|
try {
|
|
1226
|
-
|
|
1180
|
+
const setupResult = setup(ctx);
|
|
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.`);
|
|
1182
|
+
renderFn = setupResult;
|
|
1227
1183
|
notifyComponentCreated(currentAppContext, componentInstance);
|
|
1184
|
+
createdHooks.forEach((hook) => hook());
|
|
1228
1185
|
} catch (err) {
|
|
1229
1186
|
if (!handleComponentError(currentAppContext, err, componentInstance, "setup")) throw err;
|
|
1230
1187
|
} finally {
|
|
@@ -1232,8 +1189,10 @@ function createRenderer(options) {
|
|
|
1232
1189
|
}
|
|
1233
1190
|
if (vnode.props?.ref) {
|
|
1234
1191
|
const refValue = exposeCalled ? exposed : null;
|
|
1235
|
-
|
|
1236
|
-
|
|
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
|
+
});
|
|
1237
1196
|
}
|
|
1238
1197
|
if (renderFn) {
|
|
1239
1198
|
ctx.renderFn = renderFn;
|
|
@@ -1247,6 +1206,7 @@ function createRenderer(options) {
|
|
|
1247
1206
|
if (prevSubTree) {
|
|
1248
1207
|
patch(prevSubTree, subTree, container);
|
|
1249
1208
|
notifyComponentUpdated(currentAppContext, componentInstance);
|
|
1209
|
+
updatedHooks.forEach((hook) => hook());
|
|
1250
1210
|
} else mount(subTree, container, anchor);
|
|
1251
1211
|
internalVNode._subTree = subTree;
|
|
1252
1212
|
} catch (err) {
|
|
@@ -1265,103 +1225,17 @@ function createRenderer(options) {
|
|
|
1265
1225
|
notifyComponentMounted(currentAppContext, componentInstance);
|
|
1266
1226
|
vnode.cleanup = () => {
|
|
1267
1227
|
notifyComponentUnmounted(currentAppContext, componentInstance);
|
|
1268
|
-
|
|
1228
|
+
unmountHooks.forEach((hook) => hook(mountCtx));
|
|
1269
1229
|
};
|
|
1270
1230
|
}
|
|
1271
|
-
/**
|
|
1272
|
-
* Create slots object from children and slots prop.
|
|
1273
|
-
* Uses a version signal to trigger re-renders when children change.
|
|
1274
|
-
* Supports named slots via:
|
|
1275
|
-
* - `slots` prop object (e.g., slots={{ header: () => <div>...</div> }})
|
|
1276
|
-
* - `slot` prop on children (e.g., <div slot="header">...</div>)
|
|
1277
|
-
*/
|
|
1278
|
-
function createSlots(children, slotsFromProps) {
|
|
1279
|
-
const versionSignal = signal$1({ v: 0 });
|
|
1280
|
-
function extractNamedSlotsFromChildren(c) {
|
|
1281
|
-
const defaultChildren = [];
|
|
1282
|
-
const namedSlots = {};
|
|
1283
|
-
if (c == null) return {
|
|
1284
|
-
defaultChildren,
|
|
1285
|
-
namedSlots
|
|
1286
|
-
};
|
|
1287
|
-
const items = Array.isArray(c) ? c : [c];
|
|
1288
|
-
for (const child of items) if (child && typeof child === "object" && child.props && child.props.slot) {
|
|
1289
|
-
const slotName = child.props.slot;
|
|
1290
|
-
if (!namedSlots[slotName]) namedSlots[slotName] = [];
|
|
1291
|
-
namedSlots[slotName].push(child);
|
|
1292
|
-
} else defaultChildren.push(child);
|
|
1293
|
-
return {
|
|
1294
|
-
defaultChildren,
|
|
1295
|
-
namedSlots
|
|
1296
|
-
};
|
|
1297
|
-
}
|
|
1298
|
-
const slotsObj = {
|
|
1299
|
-
_children: children,
|
|
1300
|
-
_slotsFromProps: slotsFromProps || {},
|
|
1301
|
-
_version: versionSignal,
|
|
1302
|
-
_isPatching: false,
|
|
1303
|
-
default: function() {
|
|
1304
|
-
this._version.v;
|
|
1305
|
-
const c = this._children;
|
|
1306
|
-
const { defaultChildren } = extractNamedSlotsFromChildren(c);
|
|
1307
|
-
return defaultChildren.filter((child) => child != null && child !== false && child !== true);
|
|
1308
|
-
}
|
|
1309
|
-
};
|
|
1310
|
-
return new Proxy(slotsObj, { get(target, prop) {
|
|
1311
|
-
if (prop in target) return target[prop];
|
|
1312
|
-
if (typeof prop === "string") return function(scopedProps) {
|
|
1313
|
-
target._version.v;
|
|
1314
|
-
if (target._slotsFromProps && typeof target._slotsFromProps[prop] === "function") {
|
|
1315
|
-
const result = target._slotsFromProps[prop](scopedProps);
|
|
1316
|
-
if (result == null) return [];
|
|
1317
|
-
return Array.isArray(result) ? result : [result];
|
|
1318
|
-
}
|
|
1319
|
-
const { namedSlots } = extractNamedSlotsFromChildren(target._children);
|
|
1320
|
-
return namedSlots[prop] || [];
|
|
1321
|
-
};
|
|
1322
|
-
} });
|
|
1323
|
-
}
|
|
1324
|
-
/**
|
|
1325
|
-
* Normalize render result to a VNode (wrapping arrays in Fragment)
|
|
1326
|
-
* Note: Falsy values (null, undefined, false, true) from conditional rendering
|
|
1327
|
-
* are handled by mount() which guards against them, so no filtering needed here.
|
|
1328
|
-
*/
|
|
1329
|
-
function normalizeSubTree(result) {
|
|
1330
|
-
if (Array.isArray(result)) return {
|
|
1331
|
-
type: Fragment,
|
|
1332
|
-
props: {},
|
|
1333
|
-
key: null,
|
|
1334
|
-
children: result,
|
|
1335
|
-
dom: null
|
|
1336
|
-
};
|
|
1337
|
-
if (typeof result === "string" || typeof result === "number") return {
|
|
1338
|
-
type: Text,
|
|
1339
|
-
props: {},
|
|
1340
|
-
key: null,
|
|
1341
|
-
children: [],
|
|
1342
|
-
dom: null,
|
|
1343
|
-
text: result
|
|
1344
|
-
};
|
|
1345
|
-
return result;
|
|
1346
|
-
}
|
|
1347
1231
|
return {
|
|
1348
1232
|
render,
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
if (options.querySelector) container = options.querySelector(selectorOrContainer);
|
|
1354
|
-
} else container = selectorOrContainer;
|
|
1355
|
-
if (!container) {
|
|
1356
|
-
console.warn(`Container not found: ${selectorOrContainer}`);
|
|
1357
|
-
return;
|
|
1358
|
-
}
|
|
1359
|
-
render(rootComponent, container);
|
|
1360
|
-
} };
|
|
1361
|
-
}
|
|
1233
|
+
patch,
|
|
1234
|
+
mount,
|
|
1235
|
+
unmount,
|
|
1236
|
+
mountComponent
|
|
1362
1237
|
};
|
|
1363
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 };
|
|
1364
1240
|
|
|
1365
|
-
//#endregion
|
|
1366
|
-
export { AppContextKey, Fragment, InstanceLifetimes, SubscriptionHandler, Suspense, Text, Utils, createPropsProxy, createRenderer, createTopic, defineApp, defineComponent, defineFactory, defineInjectable, defineProvide, defineStore, getComponentMeta, getComponentPlugins, getCurrentInstance, getDefaultMount, getPlatformSyncProcessor, guid, handleComponentError, inject, injectApp, isLazyComponent, jsx, jsxDEV, jsxs, lazy, notifyComponentCreated, notifyComponentMounted, notifyComponentUnmounted, notifyComponentUpdated, onCleanup, onMount, provide, registerComponentPlugin, registerPendingPromise, setCurrentInstance, setDefaultMount, setPlatformSyncProcessor, signal, toSubscriber, valueOf };
|
|
1367
1241
|
//# sourceMappingURL=index.js.map
|