@fluixi/core 1.0.0-alpha.53
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/LICENSE +21 -0
- package/README.md +611 -0
- package/dist/cdn/core.global.js +3 -0
- package/dist/cli/generate.cjs +1814 -0
- package/dist/cli/generate.d.ts +7 -0
- package/dist/cli/generate.d.ts.map +1 -0
- package/dist/cli/generate.js +2580 -0
- package/dist/cli/generate.mjs +1814 -0
- package/dist/cli/index.cjs +1814 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +2580 -0
- package/dist/cli/index.mjs +1814 -0
- package/dist/cli/run.cjs +2 -0
- package/dist/cli/run.d.ts +3 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +62 -0
- package/dist/cli/run.mjs +2 -0
- package/dist/fluixi.d.ts +5 -0
- package/dist/src/cdn/chunk-PFM5O5UE.mjs +1 -0
- package/dist/src/cdn/core.cjs +1 -0
- package/dist/src/cdn/core.d.ts +16 -0
- package/dist/src/cdn/core.d.ts.map +1 -0
- package/dist/src/cdn/core.js +15 -0
- package/dist/src/cdn/core.mjs +1 -0
- package/dist/src/cdn/router-next-WNWCFVC2.mjs +1 -0
- package/dist/src/index.cjs +1 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +26 -0
- package/dist/src/index.mjs +1 -0
- package/dist/src/jsx-dev-runtime.cjs +1 -0
- package/dist/src/jsx-dev-runtime.d.ts +2 -0
- package/dist/src/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/src/jsx-dev-runtime.js +1 -0
- package/dist/src/jsx-dev-runtime.mjs +1 -0
- package/dist/src/jsx-runtime.cjs +1 -0
- package/dist/src/jsx-runtime.d.ts +7 -0
- package/dist/src/jsx-runtime.d.ts.map +1 -0
- package/dist/src/jsx-runtime.js +17 -0
- package/dist/src/jsx-runtime.mjs +1 -0
- package/dist/src/lib/client/chunk-D3VTWVNJ.mjs +1 -0
- package/dist/src/lib/client/index.cjs +1 -0
- package/dist/src/lib/client/index.d.ts +54 -0
- package/dist/src/lib/client/index.d.ts.map +1 -0
- package/dist/src/lib/client/index.js +142 -0
- package/dist/src/lib/client/index.mjs +1 -0
- package/dist/src/lib/client/router-next-UYIYMRJL.mjs +1 -0
- package/dist/src/lib/context/context.cjs +1 -0
- package/dist/src/lib/context/context.d.ts +337 -0
- package/dist/src/lib/context/context.d.ts.map +1 -0
- package/dist/src/lib/context/context.js +462 -0
- package/dist/src/lib/context/context.mjs +1 -0
- package/dist/src/lib/context/index.cjs +1 -0
- package/dist/src/lib/context/index.d.ts +3 -0
- package/dist/src/lib/context/index.d.ts.map +1 -0
- package/dist/src/lib/context/index.js +5 -0
- package/dist/src/lib/context/index.mjs +1 -0
- package/dist/src/lib/control-flow.cjs +1 -0
- package/dist/src/lib/control-flow.d.ts +4 -0
- package/dist/src/lib/control-flow.d.ts.map +1 -0
- package/dist/src/lib/control-flow.js +1 -0
- package/dist/src/lib/control-flow.mjs +1 -0
- package/dist/src/lib/core.cjs +1 -0
- package/dist/src/lib/core.d.ts +90 -0
- package/dist/src/lib/core.d.ts.map +1 -0
- package/dist/src/lib/core.js +181 -0
- package/dist/src/lib/core.mjs +1 -0
- package/dist/src/lib/directives/lit.cjs +1 -0
- package/dist/src/lib/directives/lit.d.ts +2 -0
- package/dist/src/lib/directives/lit.d.ts.map +1 -0
- package/dist/src/lib/directives/lit.js +31 -0
- package/dist/src/lib/directives/lit.mjs +0 -0
- package/dist/src/lib/env/index.cjs +1 -0
- package/dist/src/lib/env/index.d.ts +39 -0
- package/dist/src/lib/env/index.d.ts.map +1 -0
- package/dist/src/lib/env/index.js +50 -0
- package/dist/src/lib/env/index.mjs +1 -0
- package/dist/src/lib/i18n/index.cjs +1 -0
- package/dist/src/lib/i18n/index.d.ts +79 -0
- package/dist/src/lib/i18n/index.d.ts.map +1 -0
- package/dist/src/lib/i18n/index.js +127 -0
- package/dist/src/lib/i18n/index.mjs +1 -0
- package/dist/src/lib/index.cjs +1 -0
- package/dist/src/lib/index.d.ts +83 -0
- package/dist/src/lib/index.d.ts.map +1 -0
- package/dist/src/lib/index.js +147 -0
- package/dist/src/lib/index.mjs +1 -0
- package/dist/src/lib/isomorphic.cjs +1 -0
- package/dist/src/lib/isomorphic.d.ts +69 -0
- package/dist/src/lib/isomorphic.d.ts.map +1 -0
- package/dist/src/lib/isomorphic.js +92 -0
- package/dist/src/lib/isomorphic.mjs +1 -0
- package/dist/src/lib/jsx-runtime/index.cjs +1 -0
- package/dist/src/lib/jsx-runtime/index.d.ts +13 -0
- package/dist/src/lib/jsx-runtime/index.d.ts.map +1 -0
- package/dist/src/lib/jsx-runtime/index.js +23 -0
- package/dist/src/lib/jsx-runtime/index.mjs +1 -0
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.cjs +1 -0
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.d.ts +2 -0
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.js +1 -0
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.mjs +1 -0
- package/dist/src/lib/plugins/fluixi-routes-plugin.cjs +13 -0
- package/dist/src/lib/plugins/fluixi-routes-plugin.d.ts +21 -0
- package/dist/src/lib/plugins/fluixi-routes-plugin.d.ts.map +1 -0
- package/dist/src/lib/plugins/fluixi-routes-plugin.js +102 -0
- package/dist/src/lib/plugins/fluixi-routes-plugin.mjs +13 -0
- package/dist/src/lib/plugins/index.cjs +13 -0
- package/dist/src/lib/plugins/index.d.ts +4 -0
- package/dist/src/lib/plugins/index.d.ts.map +1 -0
- package/dist/src/lib/plugins/index.js +3 -0
- package/dist/src/lib/plugins/index.mjs +13 -0
- package/dist/src/lib/plugins/route-codegen.cjs +8 -0
- package/dist/src/lib/plugins/route-codegen.d.ts +13 -0
- package/dist/src/lib/plugins/route-codegen.d.ts.map +1 -0
- package/dist/src/lib/plugins/route-codegen.js +81 -0
- package/dist/src/lib/plugins/route-codegen.mjs +8 -0
- package/dist/src/lib/plugins/route-scanner.cjs +1 -0
- package/dist/src/lib/plugins/route-scanner.d.ts +39 -0
- package/dist/src/lib/plugins/route-scanner.d.ts.map +1 -0
- package/dist/src/lib/plugins/route-scanner.js +216 -0
- package/dist/src/lib/plugins/route-scanner.mjs +1 -0
- package/dist/src/lib/plugins/vite.cjs +1 -0
- package/dist/src/lib/plugins/vite.d.ts +3 -0
- package/dist/src/lib/plugins/vite.d.ts.map +1 -0
- package/dist/src/lib/plugins/vite.js +1 -0
- package/dist/src/lib/plugins/vite.mjs +1 -0
- package/dist/src/lib/render/component.cjs +1 -0
- package/dist/src/lib/render/component.d.ts +328 -0
- package/dist/src/lib/render/component.d.ts.map +1 -0
- package/dist/src/lib/render/component.js +520 -0
- package/dist/src/lib/render/component.mjs +1 -0
- package/dist/src/lib/render/index.cjs +1 -0
- package/dist/src/lib/render/index.d.ts +113 -0
- package/dist/src/lib/render/index.d.ts.map +1 -0
- package/dist/src/lib/render/index.js +201 -0
- package/dist/src/lib/render/index.mjs +1 -0
- package/dist/src/lib/render/lazy.cjs +1 -0
- package/dist/src/lib/render/lazy.d.ts +28 -0
- package/dist/src/lib/render/lazy.d.ts.map +1 -0
- package/dist/src/lib/render/lazy.js +62 -0
- package/dist/src/lib/render/lazy.mjs +1 -0
- package/dist/src/lib/render/suspense.cjs +1 -0
- package/dist/src/lib/render/suspense.d.ts +25 -0
- package/dist/src/lib/render/suspense.d.ts.map +1 -0
- package/dist/src/lib/render/suspense.js +139 -0
- package/dist/src/lib/render/suspense.mjs +1 -0
- package/dist/src/lib/router-next/data.cjs +1 -0
- package/dist/src/lib/router-next/data.d.ts +101 -0
- package/dist/src/lib/router-next/data.d.ts.map +1 -0
- package/dist/src/lib/router-next/data.js +179 -0
- package/dist/src/lib/router-next/data.mjs +1 -0
- package/dist/src/lib/router-next/index.cjs +1 -0
- package/dist/src/lib/router-next/index.d.ts +156 -0
- package/dist/src/lib/router-next/index.d.ts.map +1 -0
- package/dist/src/lib/router-next/index.js +464 -0
- package/dist/src/lib/router-next/index.mjs +1 -0
- package/dist/src/lib/server/hydration.cjs +1 -0
- package/dist/src/lib/server/hydration.d.ts +238 -0
- package/dist/src/lib/server/hydration.d.ts.map +1 -0
- package/dist/src/lib/server/hydration.js +384 -0
- package/dist/src/lib/server/hydration.mjs +1 -0
- package/dist/src/lib/server/index.cjs +16 -0
- package/dist/src/lib/server/index.d.ts +91 -0
- package/dist/src/lib/server/index.d.ts.map +1 -0
- package/dist/src/lib/server/index.js +141 -0
- package/dist/src/lib/server/index.mjs +16 -0
- package/dist/src/lib/server/reactive.cjs +1 -0
- package/dist/src/lib/server/reactive.d.ts +298 -0
- package/dist/src/lib/server/reactive.d.ts.map +1 -0
- package/dist/src/lib/server/reactive.js +472 -0
- package/dist/src/lib/server/reactive.mjs +1 -0
- package/dist/src/lib/theme/index.cjs +1 -0
- package/dist/src/lib/theme/index.d.ts +51 -0
- package/dist/src/lib/theme/index.d.ts.map +1 -0
- package/dist/src/lib/theme/index.js +79 -0
- package/dist/src/lib/theme/index.mjs +1 -0
- package/dist/src/lib/utils/index.cjs +1 -0
- package/dist/src/lib/utils/index.d.ts +379 -0
- package/dist/src/lib/utils/index.d.ts.map +1 -0
- package/dist/src/lib/utils/index.js +527 -0
- package/dist/src/lib/utils/index.mjs +1 -0
- package/dist/src/rx.cjs +1 -0
- package/dist/src/rx.d.ts +2 -0
- package/dist/src/rx.d.ts.map +1 -0
- package/dist/src/rx.js +101 -0
- package/dist/src/rx.mjs +0 -0
- package/dist/src/server.cjs +16 -0
- package/dist/src/server.d.ts +64 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +63 -0
- package/dist/src/server.mjs +16 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/package.json +128 -0
- package/src/index.ts +31 -0
- package/types/fluixi.d.ts +5 -0
- package/types/vinxi.d.ts +50 -0
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Server Reactive Primitives for Fluixi
|
|
3
|
+
* @module @fluixi/core/server/reactive
|
|
4
|
+
*
|
|
5
|
+
* Maps reactive primitives for server-side execution
|
|
6
|
+
* Following SolidJS pattern of server-specific reactive behavior
|
|
7
|
+
*
|
|
8
|
+
* Server mode:
|
|
9
|
+
* - Signals read-only snapshot
|
|
10
|
+
* - Effects run once
|
|
11
|
+
* - No scheduling
|
|
12
|
+
* - No subscriptions
|
|
13
|
+
*/
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// SERVER SIGNAL
|
|
16
|
+
// ============================================================================
|
|
17
|
+
/**
|
|
18
|
+
* Server createSignal - Returns snapshot value
|
|
19
|
+
*
|
|
20
|
+
* Section 4: Signals read-only snapshot on server
|
|
21
|
+
* No reactivity, no tracking, just initial value
|
|
22
|
+
*
|
|
23
|
+
* @template T
|
|
24
|
+
* @param {T} value - Initial value
|
|
25
|
+
* @param {SignalOptions<T>} options - SignalTuple options (ignored on server)
|
|
26
|
+
* @returns {SignalTuple<T>} Tuple of [getter, setter]
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* // On server, this returns a static snapshot
|
|
31
|
+
* const [count, setCount] = createSignal(0);
|
|
32
|
+
* console.log(count()); // 0
|
|
33
|
+
* setCount(1); // Updates value but triggers no effects
|
|
34
|
+
* console.log(count()); // 1
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export function createSignal(value, options) {
|
|
38
|
+
// Server: Simple read/write, no reactivity
|
|
39
|
+
let current = value;
|
|
40
|
+
const read = (() => current);
|
|
41
|
+
const write = (newValue) => {
|
|
42
|
+
if (typeof newValue === 'function') {
|
|
43
|
+
current = newValue(current);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
current = newValue;
|
|
47
|
+
}
|
|
48
|
+
return current;
|
|
49
|
+
};
|
|
50
|
+
return [read, write];
|
|
51
|
+
}
|
|
52
|
+
// ============================================================================
|
|
53
|
+
// SERVER EFFECT
|
|
54
|
+
// ============================================================================
|
|
55
|
+
/**
|
|
56
|
+
* Server createEffect - Runs once, no tracking
|
|
57
|
+
*
|
|
58
|
+
* Section 4: Effects run once on server, no scheduling
|
|
59
|
+
* Execute immediately and return no-op disposer
|
|
60
|
+
*
|
|
61
|
+
* @param {(v?: any) => any} fn - Effect function
|
|
62
|
+
* @param {any} value - Initial value (optional)
|
|
63
|
+
* @param {any} options - Effect options (ignored on server)
|
|
64
|
+
* @returns {{ dispose: () => void }} Disposer object
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* // On server, runs once immediately
|
|
69
|
+
* createEffect(() => {
|
|
70
|
+
* console.log('This runs once');
|
|
71
|
+
* });
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export function createEffect(fn, value, options) {
|
|
75
|
+
// Server: Run once, no tracking, no scheduling
|
|
76
|
+
try {
|
|
77
|
+
fn(value);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
console.error('[Fluixi Server] Effect error:', error);
|
|
81
|
+
}
|
|
82
|
+
// Return no-op disposer
|
|
83
|
+
return { dispose: () => { } };
|
|
84
|
+
}
|
|
85
|
+
// ============================================================================
|
|
86
|
+
// SERVER MEMO
|
|
87
|
+
// ============================================================================
|
|
88
|
+
/**
|
|
89
|
+
* Server createMemo - Compute once, return static accessor
|
|
90
|
+
*
|
|
91
|
+
* Section 4: No tracking on server, single evaluation
|
|
92
|
+
* Memoizes value at creation time
|
|
93
|
+
*
|
|
94
|
+
* @template T
|
|
95
|
+
* @param {(v?: T) => T} fn - Computation function
|
|
96
|
+
* @param {T} value - Initial value (optional)
|
|
97
|
+
* @param {any} options - Memo options (ignored on server)
|
|
98
|
+
* @returns {Accessor<T>} Static accessor
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* const [count] = createSignal(5);
|
|
103
|
+
* const doubled = createMemo(() => count() * 2);
|
|
104
|
+
* console.log(doubled()); // 10 (computed once)
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export function createMemo(fn, value, options) {
|
|
108
|
+
// Server: Compute once, no reactivity
|
|
109
|
+
const computed = fn(value);
|
|
110
|
+
return (() => computed);
|
|
111
|
+
}
|
|
112
|
+
// ============================================================================
|
|
113
|
+
// SERVER ROOT
|
|
114
|
+
// ============================================================================
|
|
115
|
+
/**
|
|
116
|
+
* Server createRoot - Creates owner but no reactive tracking
|
|
117
|
+
*
|
|
118
|
+
* Section 5: Owners exist on server for tree structure
|
|
119
|
+
* Needed for context and cleanup, but no reactive tracking
|
|
120
|
+
*
|
|
121
|
+
* @template T
|
|
122
|
+
* @param {(dispose: () => void) => T} fn - Root function
|
|
123
|
+
* @returns {T} Function result
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```typescript
|
|
127
|
+
* const result = createRoot((dispose) => {
|
|
128
|
+
* // Server: Executes once, maintains owner tree
|
|
129
|
+
* return <App />;
|
|
130
|
+
* });
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
export function createRoot(fn) {
|
|
134
|
+
// Server: Execute function with no-op disposer
|
|
135
|
+
// Owner tree maintained for context/cleanup
|
|
136
|
+
const cleanups = [];
|
|
137
|
+
const dispose = () => {
|
|
138
|
+
cleanups.forEach((cleanup) => {
|
|
139
|
+
try {
|
|
140
|
+
cleanup();
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
console.error('[Fluixi Server] Cleanup error:', error);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
cleanups.length = 0;
|
|
147
|
+
};
|
|
148
|
+
try {
|
|
149
|
+
return fn(dispose);
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
dispose();
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// ============================================================================
|
|
157
|
+
// SERVER BATCH
|
|
158
|
+
// ============================================================================
|
|
159
|
+
/**
|
|
160
|
+
* Server batch - Execute immediately, no batching
|
|
161
|
+
*
|
|
162
|
+
* Section 4: No scheduling on server
|
|
163
|
+
* Just runs the function synchronously
|
|
164
|
+
*
|
|
165
|
+
* @template T
|
|
166
|
+
* @param {() => T} fn - Function to batch
|
|
167
|
+
* @returns {T} Function result
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```typescript
|
|
171
|
+
* batch(() => {
|
|
172
|
+
* setCount(1);
|
|
173
|
+
* setName('Alice');
|
|
174
|
+
* }); // Executes immediately
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
export function batch(fn) {
|
|
178
|
+
// Server: No batching needed, just run
|
|
179
|
+
return fn();
|
|
180
|
+
}
|
|
181
|
+
// ============================================================================
|
|
182
|
+
// SERVER UNTRACK
|
|
183
|
+
// ============================================================================
|
|
184
|
+
/**
|
|
185
|
+
* Server untrack - Execute function (already untracked)
|
|
186
|
+
*
|
|
187
|
+
* Section 4: No tracking on server anyway
|
|
188
|
+
* This is a no-op but exists for API compatibility
|
|
189
|
+
*
|
|
190
|
+
* @template T
|
|
191
|
+
* @param {() => T} fn - Function to run untracked
|
|
192
|
+
* @returns {T} Function result
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```typescript
|
|
196
|
+
* untrack(() => {
|
|
197
|
+
* return signal(); // Not tracked (but nothing is on server)
|
|
198
|
+
* });
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
export function untrack(fn) {
|
|
202
|
+
// Server: Already untracked, just run
|
|
203
|
+
return fn();
|
|
204
|
+
}
|
|
205
|
+
// ============================================================================
|
|
206
|
+
// SERVER CLEANUP
|
|
207
|
+
// ============================================================================
|
|
208
|
+
let currentCleanups = null;
|
|
209
|
+
/**
|
|
210
|
+
* Server onCleanup - Register cleanup function
|
|
211
|
+
*
|
|
212
|
+
* Section 5: Cleanup still needed for SSR resource management
|
|
213
|
+
* Stores cleanup for execution when root disposes
|
|
214
|
+
*
|
|
215
|
+
* @param {() => void} fn - Cleanup function
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* ```typescript
|
|
219
|
+
* createRoot((dispose) => {
|
|
220
|
+
* onCleanup(() => {
|
|
221
|
+
* console.log('Cleanup on dispose');
|
|
222
|
+
* });
|
|
223
|
+
* return result;
|
|
224
|
+
* });
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
export function onCleanup(fn) {
|
|
228
|
+
if (currentCleanups) {
|
|
229
|
+
currentCleanups.push(fn);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// ============================================================================
|
|
233
|
+
// SERVER OWNER
|
|
234
|
+
// ============================================================================
|
|
235
|
+
let currentOwner = null;
|
|
236
|
+
/**
|
|
237
|
+
* Server getOwner - Get current reactive owner
|
|
238
|
+
*
|
|
239
|
+
* Section 5: Owner tree maintained on server for context
|
|
240
|
+
*
|
|
241
|
+
* @returns {RootOwner | null} Current owner or null
|
|
242
|
+
*/
|
|
243
|
+
export function getOwner() {
|
|
244
|
+
return currentOwner;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Server runWithOwner - Run function with specific owner
|
|
248
|
+
*
|
|
249
|
+
* Section 5: Owner switching for proper context nesting
|
|
250
|
+
*
|
|
251
|
+
* @template T
|
|
252
|
+
* @param {RootOwner | null} owner - Owner to run with
|
|
253
|
+
* @param {() => T} fn - Function to run
|
|
254
|
+
* @returns {T} Function result
|
|
255
|
+
*/
|
|
256
|
+
export function runWithOwner(owner, fn) {
|
|
257
|
+
const prev = currentOwner;
|
|
258
|
+
currentOwner = owner;
|
|
259
|
+
try {
|
|
260
|
+
return fn();
|
|
261
|
+
}
|
|
262
|
+
finally {
|
|
263
|
+
currentOwner = prev;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// ============================================================================
|
|
267
|
+
// SERVER CONTEXT
|
|
268
|
+
// ============================================================================
|
|
269
|
+
const contextMap = new Map();
|
|
270
|
+
/**
|
|
271
|
+
* Server createContext - Create context with default value
|
|
272
|
+
*
|
|
273
|
+
* Section 9: Context lookup-based, no subscriptions on server
|
|
274
|
+
*
|
|
275
|
+
* @template T
|
|
276
|
+
* @param {T} defaultValue - Default context value
|
|
277
|
+
* @returns {Context<T>} Context object
|
|
278
|
+
*
|
|
279
|
+
* @example
|
|
280
|
+
* ```typescript
|
|
281
|
+
* const ThemeContext = createContext('light');
|
|
282
|
+
* ```
|
|
283
|
+
*/
|
|
284
|
+
export function createContext(defaultValue) {
|
|
285
|
+
const id = Symbol('context');
|
|
286
|
+
const Provider = (props) => {
|
|
287
|
+
// Server: Store value in context map
|
|
288
|
+
const prevValue = contextMap.get(id);
|
|
289
|
+
contextMap.set(id, props.value);
|
|
290
|
+
try {
|
|
291
|
+
return props.children;
|
|
292
|
+
}
|
|
293
|
+
finally {
|
|
294
|
+
// Restore previous value
|
|
295
|
+
if (prevValue !== undefined) {
|
|
296
|
+
contextMap.set(id, prevValue);
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
contextMap.delete(id);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
return {
|
|
304
|
+
id,
|
|
305
|
+
Provider,
|
|
306
|
+
defaultValue: defaultValue,
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Server useContext - Retrieve context value
|
|
311
|
+
*
|
|
312
|
+
* Section 9: No subscriptions on server, just lookup
|
|
313
|
+
*
|
|
314
|
+
* @template T
|
|
315
|
+
* @param {Context<T>} context - Context to use
|
|
316
|
+
* @returns {T} Context value
|
|
317
|
+
*
|
|
318
|
+
* @example
|
|
319
|
+
* ```typescript
|
|
320
|
+
* const theme = useContext(ThemeContext);
|
|
321
|
+
* ```
|
|
322
|
+
*/
|
|
323
|
+
export function useContext(context) {
|
|
324
|
+
// Server: Simple lookup, no subscription
|
|
325
|
+
const value = contextMap.get(context.id);
|
|
326
|
+
return value !== undefined ? value : context.defaultValue;
|
|
327
|
+
}
|
|
328
|
+
// ============================================================================
|
|
329
|
+
// SERVER COMPUTED
|
|
330
|
+
// ============================================================================
|
|
331
|
+
/**
|
|
332
|
+
* Server createComputed - Alias for createEffect
|
|
333
|
+
*
|
|
334
|
+
* On server, computed values run once like effects
|
|
335
|
+
*
|
|
336
|
+
* @param {() => any} fn - Computation function
|
|
337
|
+
* @returns {{ dispose: () => void }} Disposer
|
|
338
|
+
*/
|
|
339
|
+
export function createComputed(fn) {
|
|
340
|
+
return createEffect(fn);
|
|
341
|
+
}
|
|
342
|
+
// ============================================================================
|
|
343
|
+
// SERVER RENDER EFFECT
|
|
344
|
+
// ============================================================================
|
|
345
|
+
/**
|
|
346
|
+
* Server createRenderEffect - Runs once for SSR rendering
|
|
347
|
+
*
|
|
348
|
+
* @param {() => any} fn - Render effect function
|
|
349
|
+
* @returns {{ dispose: () => void }} Disposer
|
|
350
|
+
*/
|
|
351
|
+
export function createRenderEffect(fn) {
|
|
352
|
+
return createEffect(fn);
|
|
353
|
+
}
|
|
354
|
+
// ============================================================================
|
|
355
|
+
// SERVER DEFERRED
|
|
356
|
+
// ============================================================================
|
|
357
|
+
/**
|
|
358
|
+
* Server createDeferred - No deferring on server
|
|
359
|
+
*
|
|
360
|
+
* @template T
|
|
361
|
+
* @param {() => T} fn - Deferred computation
|
|
362
|
+
* @returns {Accessor<T>} Accessor
|
|
363
|
+
*/
|
|
364
|
+
export function createDeferred(fn) {
|
|
365
|
+
return createMemo(fn);
|
|
366
|
+
}
|
|
367
|
+
// ============================================================================
|
|
368
|
+
// SERVER SELECTOR
|
|
369
|
+
// ============================================================================
|
|
370
|
+
/**
|
|
371
|
+
* Server createSelector - Returns static equality check
|
|
372
|
+
*
|
|
373
|
+
* @template T
|
|
374
|
+
* @param {() => T} source - Source value
|
|
375
|
+
* @returns {(key: T) => boolean} Selector function
|
|
376
|
+
*/
|
|
377
|
+
// ENVIRONMENT
|
|
378
|
+
export function createSelector(source) {
|
|
379
|
+
const value = source();
|
|
380
|
+
return (key) => key === value;
|
|
381
|
+
}
|
|
382
|
+
// ============================================================================
|
|
383
|
+
// SERVER RESOURCE
|
|
384
|
+
// ============================================================================
|
|
385
|
+
/**
|
|
386
|
+
* Server createResource - Stub for resource creation
|
|
387
|
+
*
|
|
388
|
+
* @param source Source signal or value
|
|
389
|
+
* @param fetcher Fetcher function
|
|
390
|
+
* @param options Resource options
|
|
391
|
+
*/
|
|
392
|
+
export function createResource(source, fetcher, options) {
|
|
393
|
+
return [
|
|
394
|
+
() => undefined,
|
|
395
|
+
{
|
|
396
|
+
mutate: (v) => v,
|
|
397
|
+
refetch: () => { },
|
|
398
|
+
},
|
|
399
|
+
];
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Server createStore — plain object wrapper, no reactivity.
|
|
403
|
+
* Mirrors the client API so shared code compiles on both sides.
|
|
404
|
+
*/
|
|
405
|
+
export function createStore(init) {
|
|
406
|
+
const state = { ...init };
|
|
407
|
+
function setStore(keyOrPatch, value) {
|
|
408
|
+
if (typeof keyOrPatch === 'object' &&
|
|
409
|
+
keyOrPatch !== null &&
|
|
410
|
+
!Array.isArray(keyOrPatch)) {
|
|
411
|
+
for (const k of Object.keys(keyOrPatch)) {
|
|
412
|
+
const v = keyOrPatch[k];
|
|
413
|
+
state[k] = typeof v === 'function' ? v(state[k]) : v;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
else {
|
|
417
|
+
state[keyOrPatch] =
|
|
418
|
+
typeof value === 'function' ? value(state[keyOrPatch]) : value;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return [state, setStore];
|
|
422
|
+
}
|
|
423
|
+
// ============================================================================
|
|
424
|
+
// SERVER TRANSITION
|
|
425
|
+
// ============================================================================
|
|
426
|
+
/**
|
|
427
|
+
* Server startTransition - Execute immediately
|
|
428
|
+
*
|
|
429
|
+
* @param fn Transition function
|
|
430
|
+
*/
|
|
431
|
+
export function startTransition(fn) {
|
|
432
|
+
fn();
|
|
433
|
+
}
|
|
434
|
+
// ============================================================================
|
|
435
|
+
// ENVIRONMENT
|
|
436
|
+
// ============================================================================
|
|
437
|
+
// ENVIRONMENT
|
|
438
|
+
// ============================================================================
|
|
439
|
+
/**
|
|
440
|
+
* Check if running on server
|
|
441
|
+
*/
|
|
442
|
+
export const isServer = true;
|
|
443
|
+
/**
|
|
444
|
+
* Check if running on client
|
|
445
|
+
*/
|
|
446
|
+
export const isClient = false;
|
|
447
|
+
// ============================================================================
|
|
448
|
+
// COMPATIBILITY
|
|
449
|
+
// ============================================================================
|
|
450
|
+
/**
|
|
451
|
+
* Server sharedConfig - Empty config object for compatibility
|
|
452
|
+
*/
|
|
453
|
+
export const sharedConfig = {
|
|
454
|
+
context: null,
|
|
455
|
+
owner: null,
|
|
456
|
+
};
|
|
457
|
+
/**
|
|
458
|
+
* Set current reactive owner (for internal use)
|
|
459
|
+
* @internal
|
|
460
|
+
*/
|
|
461
|
+
export function setOwner(owner) {
|
|
462
|
+
currentOwner = owner;
|
|
463
|
+
sharedConfig.owner = owner;
|
|
464
|
+
sharedConfig.context = owner;
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Get shared config (for compatibility)
|
|
468
|
+
* @internal
|
|
469
|
+
*/
|
|
470
|
+
export function getSharedConfig() {
|
|
471
|
+
return sharedConfig;
|
|
472
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function f(e,t){let o=e;return[(()=>o),c=>(typeof c=="function"?o=c(o):o=c,o)]}function T(e,t,o){try{e(t)}catch(n){console.error("[Fluixi Server] Effect error:",n)}return{dispose:()=>{}}}function p(e,t,o){let n=e(t);return(()=>n)}function d(e){let t=[],o=()=>{t.forEach(n=>{try{n()}catch(r){console.error("[Fluixi Server] Cleanup error:",r)}}),t.length=0};try{return e(o)}catch(n){throw o(),n}}function x(e){return e()}function y(e){return e()}var l=null;function v(e){l&&l.push(e)}var s=null;function S(){return s}function g(e,t){let o=s;s=e;try{return t()}finally{s=o}}var i=new Map;function w(e){let t=Symbol("context");return{id:t,Provider:n=>{let r=i.get(t);i.set(t,n.value);try{return n.children}finally{r!==void 0?i.set(t,r):i.delete(t)}},defaultValue:e}}function C(e){let t=i.get(e.id);return t!==void 0?t:e.defaultValue}function h(e){return T(e)}function A(e){return T(e)}function K(e){return p(e)}function R(e){let t=e();return o=>o===t}function O(e,t,o){return[()=>{},{mutate:n=>n,refetch:()=>{}}]}function b(e){let t={...e};function o(n,r){if(typeof n=="object"&&n!==null&&!Array.isArray(n))for(let c of Object.keys(n)){let u=n[c];t[c]=typeof u=="function"?u(t[c]):u}else t[n]=typeof r=="function"?r(t[n]):r}return[t,o]}function m(e){e()}var j=!0,F=!1,a={context:null,owner:null};function E(e){s=e,a.owner=e,a.context=e}function k(){return a}export{x as batch,h as createComputed,w as createContext,K as createDeferred,T as createEffect,p as createMemo,A as createRenderEffect,O as createResource,d as createRoot,R as createSelector,f as createSignal,b as createStore,S as getOwner,k as getSharedConfig,F as isClient,j as isServer,v as onCleanup,g as runWithOwner,E as setOwner,a as sharedConfig,m as startTransition,y as untrack,C as useContext};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var s=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var x=(e,t)=>{for(var r in t)s(e,r,{get:t[r],enumerable:!0})},S=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of v(t))!p.call(e,i)&&i!==r&&s(e,i,{get:()=>t[i],enumerable:!(o=y(t,i))||o.enumerable});return e};var k=e=>S(s({},"__esModule",{value:!0}),e);var I={};x(I,{createTheme:()=>O});module.exports=k(I);var l=require("@fluixi/reactive/signal");function b(){let e=new Map;return{getItem:t=>e.has(t)?e.get(t):null,setItem:(t,r)=>{e.set(t,String(r))},removeItem:t=>{e.delete(t)},clear:()=>e.clear(),key:t=>Array.from(e.keys())[t]??null,get length(){return e.size}}}var a=typeof localStorage<"u"?localStorage:b(),c={get window(){return typeof window<"u"?window:void 0},get document(){return typeof document<"u"?document:void 0}};function w(e){return e?e===!0?{dark:"dark",light:"light"}:e:null}function O(e){let t=e.storageKey??"theme",r=e.attribute??"data-theme",o=w(e.system),i=()=>{let n=a.getItem(t);return n&&e.themes.includes(n)?n:o&&c.window?.matchMedia?.("(prefers-color-scheme: dark)")?.matches?o.dark:o?o.light:e.default},[d,f]=(0,l.createSignal)(i()),[T,u]=(0,l.createSignal)(!1),g=n=>{c.document?.documentElement.setAttribute(r,n);try{a.setItem(t,n)}catch{}},m=n=>{if(!e.themes.includes(n))return;let h=d();f(()=>n),g(n),e.onChange?.(n,h),e.load&&(u(!0),e.onLoading?.(n),Promise.resolve(e.load(n)).finally(()=>{u(!1),e.onLoaded?.(n)}))};return{value:d,isLoading:T,set:m,toggle:()=>{let n=e.themes.indexOf(d());m(e.themes[(n+1)%e.themes.length])},init:()=>g(d()),headScript:()=>`<script>(function(){try{var c=${JSON.stringify({k:t,a:r,d:e.default,sys:o})},t=localStorage.getItem(c.k);if(!t&&c.sys)t=matchMedia('(prefers-color-scheme: dark)').matches?c.sys.dark:c.sys.light;if(!t)t=c.d;document.documentElement.setAttribute(c.a,t);}catch(e){}})();<\/script>`}}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createTheme — a reusable, SSR-safe theme store so every Fluixi app gets the whole
|
|
3
|
+
* theme workflow (detect → persist → apply → toggle, + the no-flash head script)
|
|
4
|
+
* without rewriting it. Generic over an arbitrary theme list (not just light/dark),
|
|
5
|
+
* with optional async theme loading and lifecycle hooks.
|
|
6
|
+
*
|
|
7
|
+
* Built on the universal `storage` + `env` utilities, so reading the stored theme at
|
|
8
|
+
* module-eval and touching `document`/`matchMedia` are safe on the server.
|
|
9
|
+
*/
|
|
10
|
+
import { type Accessor } from '@fluixi/reactive/signal';
|
|
11
|
+
export interface ThemeOptions<T extends string> {
|
|
12
|
+
/** The full set of themes. `toggle()` cycles through them in order. */
|
|
13
|
+
themes: readonly T[];
|
|
14
|
+
/** Theme used when nothing is stored and system preference doesn't apply. */
|
|
15
|
+
default: T;
|
|
16
|
+
/** localStorage key the choice is persisted under (default `"theme"`). */
|
|
17
|
+
storageKey?: string;
|
|
18
|
+
/** Attribute set on `<html>` to drive CSS (default `"data-theme"`). */
|
|
19
|
+
attribute?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Follow `prefers-color-scheme` when there is no stored choice. `true` assumes the
|
|
22
|
+
* themes literally include `"dark"`/`"light"`; pass `{ dark, light }` to map explicitly.
|
|
23
|
+
*/
|
|
24
|
+
system?: boolean | {
|
|
25
|
+
dark: T;
|
|
26
|
+
light: T;
|
|
27
|
+
};
|
|
28
|
+
/** Optional async work per theme (e.g. lazy-import a CSS bundle). Drives `isLoading()`. */
|
|
29
|
+
load?: (theme: T) => void | Promise<void>;
|
|
30
|
+
/** Fired after a theme is applied. */
|
|
31
|
+
onChange?: (next: T, prev: T | undefined) => void;
|
|
32
|
+
/** Fired when an async `load` starts / finishes. */
|
|
33
|
+
onLoading?: (theme: T) => void;
|
|
34
|
+
onLoaded?: (theme: T) => void;
|
|
35
|
+
}
|
|
36
|
+
export interface Theme<T extends string> {
|
|
37
|
+
/** Reactive current theme. */
|
|
38
|
+
value: Accessor<T>;
|
|
39
|
+
/** Reactive — true while an async `load` is running. */
|
|
40
|
+
isLoading: Accessor<boolean>;
|
|
41
|
+
/** Set a specific theme (persists, applies, runs `load`/hooks). */
|
|
42
|
+
set: (theme: T) => void;
|
|
43
|
+
/** Cycle to the next theme in `themes`. */
|
|
44
|
+
toggle: () => void;
|
|
45
|
+
/** Apply the current theme to the DOM (call once on client mount). */
|
|
46
|
+
init: () => void;
|
|
47
|
+
/** Inline `<script>` for `<head>` that sets the attribute BEFORE first paint (no flash). */
|
|
48
|
+
headScript: () => string;
|
|
49
|
+
}
|
|
50
|
+
export declare function createTheme<T extends string>(options: ThemeOptions<T>): Theme<T>;
|
|
51
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/theme/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGtE,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,MAAM;IAC5C,uEAAuE;IACvE,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC;IACrB,6EAA6E;IAC7E,OAAO,EAAE,CAAC,CAAC;IACX,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG;QAAE,IAAI,EAAE,CAAC,CAAC;QAAC,KAAK,EAAE,CAAC,CAAA;KAAE,CAAC;IACzC,2FAA2F;IAC3F,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,sCAAsC;IACtC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,SAAS,KAAK,IAAI,CAAC;IAClD,oDAAoD;IACpD,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,KAAK,CAAC,CAAC,SAAS,MAAM;IACrC,8BAA8B;IAC9B,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACnB,wDAAwD;IACxD,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7B,mEAAmE;IACnE,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IACxB,2CAA2C;IAC3C,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,sEAAsE;IACtE,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,4FAA4F;IAC5F,UAAU,EAAE,MAAM,MAAM,CAAC;CAC1B;AAUD,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAiEhF"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createTheme — a reusable, SSR-safe theme store so every Fluixi app gets the whole
|
|
3
|
+
* theme workflow (detect → persist → apply → toggle, + the no-flash head script)
|
|
4
|
+
* without rewriting it. Generic over an arbitrary theme list (not just light/dark),
|
|
5
|
+
* with optional async theme loading and lifecycle hooks.
|
|
6
|
+
*
|
|
7
|
+
* Built on the universal `storage` + `env` utilities, so reading the stored theme at
|
|
8
|
+
* module-eval and touching `document`/`matchMedia` are safe on the server.
|
|
9
|
+
*/
|
|
10
|
+
import { createSignal } from '@fluixi/reactive/signal';
|
|
11
|
+
import { storage, env } from '../env/index.js';
|
|
12
|
+
function systemMap(system) {
|
|
13
|
+
if (!system)
|
|
14
|
+
return null;
|
|
15
|
+
if (system === true)
|
|
16
|
+
return { dark: 'dark', light: 'light' };
|
|
17
|
+
return system;
|
|
18
|
+
}
|
|
19
|
+
export function createTheme(options) {
|
|
20
|
+
const storageKey = options.storageKey ?? 'theme';
|
|
21
|
+
const attribute = options.attribute ?? 'data-theme';
|
|
22
|
+
const sys = systemMap(options.system);
|
|
23
|
+
const detectInitial = () => {
|
|
24
|
+
const stored = storage.getItem(storageKey);
|
|
25
|
+
if (stored && options.themes.includes(stored))
|
|
26
|
+
return stored;
|
|
27
|
+
if (sys && env.window?.matchMedia?.('(prefers-color-scheme: dark)')?.matches)
|
|
28
|
+
return sys.dark;
|
|
29
|
+
if (sys)
|
|
30
|
+
return sys.light;
|
|
31
|
+
return options.default;
|
|
32
|
+
};
|
|
33
|
+
const [value, setValue] = createSignal(detectInitial());
|
|
34
|
+
const [isLoading, setLoading] = createSignal(false);
|
|
35
|
+
const apply = (t) => {
|
|
36
|
+
env.document?.documentElement.setAttribute(attribute, t);
|
|
37
|
+
try {
|
|
38
|
+
storage.setItem(storageKey, t);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
/* best-effort persistence */
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const set = (t) => {
|
|
45
|
+
if (!options.themes.includes(t))
|
|
46
|
+
return;
|
|
47
|
+
const prev = value();
|
|
48
|
+
setValue(() => t);
|
|
49
|
+
apply(t);
|
|
50
|
+
options.onChange?.(t, prev);
|
|
51
|
+
if (options.load) {
|
|
52
|
+
setLoading(true);
|
|
53
|
+
options.onLoading?.(t);
|
|
54
|
+
Promise.resolve(options.load(t)).finally(() => {
|
|
55
|
+
setLoading(false);
|
|
56
|
+
options.onLoaded?.(t);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const toggle = () => {
|
|
61
|
+
const i = options.themes.indexOf(value());
|
|
62
|
+
set(options.themes[(i + 1) % options.themes.length]);
|
|
63
|
+
};
|
|
64
|
+
const init = () => apply(value());
|
|
65
|
+
const headScript = () => {
|
|
66
|
+
const cfg = JSON.stringify({
|
|
67
|
+
k: storageKey,
|
|
68
|
+
a: attribute,
|
|
69
|
+
d: options.default,
|
|
70
|
+
sys,
|
|
71
|
+
});
|
|
72
|
+
// Runs before paint: read stored choice (or system pref), set the attribute, so the
|
|
73
|
+
// server-rendered HTML never flashes the default theme before hydration.
|
|
74
|
+
return (`<script>(function(){try{var c=${cfg},t=localStorage.getItem(c.k);` +
|
|
75
|
+
`if(!t&&c.sys)t=matchMedia('(prefers-color-scheme: dark)').matches?c.sys.dark:c.sys.light;` +
|
|
76
|
+
`if(!t)t=c.d;document.documentElement.setAttribute(c.a,t);}catch(e){}})();</script>`);
|
|
77
|
+
};
|
|
78
|
+
return { value, isLoading, set, toggle, init, headScript };
|
|
79
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createSignal as u}from"@fluixi/reactive/signal";function h(){let e=new Map;return{getItem:n=>e.has(n)?e.get(n):null,setItem:(n,o)=>{e.set(n,String(o))},removeItem:n=>{e.delete(n)},clear:()=>e.clear(),key:n=>Array.from(e.keys())[n]??null,get length(){return e.size}}}var d=typeof localStorage<"u"?localStorage:h(),s={get window(){return typeof window<"u"?window:void 0},get document(){return typeof document<"u"?document:void 0}};function y(e){return e?e===!0?{dark:"dark",light:"light"}:e:null}function w(e){let n=e.storageKey??"theme",o=e.attribute??"data-theme",r=y(e.system),g=()=>{let t=d.getItem(n);return t&&e.themes.includes(t)?t:r&&s.window?.matchMedia?.("(prefers-color-scheme: dark)")?.matches?r.dark:r?r.light:e.default},[i,m]=u(g()),[f,a]=u(!1),c=t=>{s.document?.documentElement.setAttribute(o,t);try{d.setItem(n,t)}catch{}},l=t=>{if(!e.themes.includes(t))return;let T=i();m(()=>t),c(t),e.onChange?.(t,T),e.load&&(a(!0),e.onLoading?.(t),Promise.resolve(e.load(t)).finally(()=>{a(!1),e.onLoaded?.(t)}))};return{value:i,isLoading:f,set:l,toggle:()=>{let t=e.themes.indexOf(i());l(e.themes[(t+1)%e.themes.length])},init:()=>c(i()),headScript:()=>`<script>(function(){try{var c=${JSON.stringify({k:n,a:o,d:e.default,sys:r})},t=localStorage.getItem(c.k);if(!t&&c.sys)t=matchMedia('(prefers-color-scheme: dark)').matches?c.sys.dark:c.sys.light;if(!t)t=c.d;document.documentElement.setAttribute(c.a,t);}catch(e){}})();<\/script>`}}export{w as createTheme};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var i=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var m=(e,t)=>{for(var r in t)i(e,r,{get:t[r],enumerable:!0})},y=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of T(t))!p.call(e,o)&&o!==r&&i(e,o,{get:()=>t[o],enumerable:!(n=f(t,o))||n.enumerable});return e};var g=e=>y(i({},"__esModule",{value:!0}),e);var _={};m(_,{camelCase:()=>K,capitalize:()=>P,clamp:()=>k,debounce:()=>l,deepClone:()=>s,deepMerge:()=>u,formatBytes:()=>M,formatNumber:()=>b,groupBy:()=>E,isDefined:()=>D,isEmpty:()=>B,kebabCase:()=>w,memoize:()=>d,omit:()=>C,pick:()=>O,pipe:()=>R,random:()=>A,range:()=>S,retry:()=>c,sleep:()=>z,throttle:()=>x,uniqueId:()=>h});module.exports=g(_);function l(e,t){let r;return(...n)=>{clearTimeout(r),r=setTimeout(()=>e(...n),t)}}function x(e,t){let r;return(...n)=>{r||(e(...n),r=!0,setTimeout(()=>r=!1,t))}}function d(e){let t=new Map;return((...r)=>{let n=JSON.stringify(r);if(t.has(n))return t.get(n);let o=e(...r);return t.set(n,o),o})}function s(e){if(e===null||typeof e!="object")return e;if(e instanceof Date)return new Date(e.getTime());if(e instanceof Array)return Array.from(e).map(r=>s(r));if(e instanceof Set)return new Set(Array.from(e).map(r=>s(r)));if(e instanceof Map)return new Map(Array.from(e.entries()).map(([r,n])=>[s(r),s(n)]));let t={};for(let r in e)e.hasOwnProperty(r)&&(t[r]=s(e[r]));return t}function u(...e){let t={};for(let r of e)for(let n in r)if(r.hasOwnProperty(n)){let o=r[n];o!==null&&typeof o=="object"&&!Array.isArray(o)?t[n]=u(t[n]||{},o):t[n]=o}return t}function h(e=""){return e+Math.random().toString(36).substr(2,9)}function b(e){return e.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")}function M(e,t=2){if(e===0)return"0 Bytes";let r=1024,n=t<0?0:t,o=["Bytes","KB","MB","GB","TB","PB"],a=Math.floor(Math.log(e)/Math.log(r));return parseFloat((e/Math.pow(r,a)).toFixed(n))+" "+o[a]}function P(e){return e.charAt(0).toUpperCase()+e.slice(1)}function w(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[\s_]+/g,"-").toLowerCase()}function K(e){return e.replace(/[-_\s](.)/g,(t,r)=>r.toUpperCase())}function k(e,t,r){return Math.min(Math.max(e,t),r)}function A(e,t){return Math.floor(Math.random()*(t-e+1))+e}function B(e){return e==null?!0:typeof e=="string"?e.trim().length===0:Array.isArray(e)?e.length===0:typeof e=="object"?Object.keys(e).length===0:!1}function O(e,...t){let r={};return t.forEach(n=>{n in e&&(r[n]=e[n])}),r}function C(e,...t){let r={...e};return t.forEach(n=>{delete r[n]}),r}function E(e,t){return e.reduce((r,n)=>{let o=t(n),a=r.get(o)||[];return a.push(n),r.set(o,a),r},new Map)}function S(e,t,r=1){let n=[];for(let o=e;o<=t;o+=r)n.push(o);return n}async function c(e,t=3,r=1e3){try{return await e()}catch(n){if(t<=0)throw n;return await new Promise(o=>setTimeout(o,r)),c(e,t-1,r)}}function z(e){return new Promise(t=>setTimeout(t,e))}function D(e){return e!=null}function R(...e){return t=>e.reduce((r,n)=>n(r),t)}
|