@fluixi/core 1.0.0-alpha.91 → 1.0.0-alpha.93
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/cdn/core.global.js +2 -2
- package/dist/src/cdn/{chunk-MDJLC3PE.mjs → chunk-7XM7Q5VR.mjs} +271 -229
- package/dist/src/cdn/core.cjs +360 -253
- package/dist/src/cdn/core.mjs +92 -20
- package/dist/src/cdn/{router-JYFZP3EZ.mjs → router-VOY43YNM.mjs} +7 -3
- package/dist/src/index.cjs +547 -232
- package/dist/src/index.mjs +547 -223
- package/dist/src/lib/client/chunk-QT3RFKH6.mjs +53 -0
- package/dist/src/lib/client/index.cjs +310 -176
- package/dist/src/lib/client/index.d.ts.map +1 -1
- package/dist/src/lib/client/index.js +33 -18
- package/dist/src/lib/client/index.mjs +86 -15
- package/dist/src/lib/client/{router-I66EJO2Y.mjs → router-ADTS55OP.mjs} +244 -99
- package/dist/src/lib/context/context.cjs +35 -72
- package/dist/src/lib/context/context.d.ts +45 -291
- package/dist/src/lib/context/context.d.ts.map +1 -1
- package/dist/src/lib/context/context.js +65 -397
- package/dist/src/lib/context/context.mjs +38 -73
- package/dist/src/lib/context/index.cjs +35 -72
- package/dist/src/lib/context/index.d.ts +2 -2
- package/dist/src/lib/context/index.d.ts.map +1 -1
- package/dist/src/lib/context/index.js +1 -5
- package/dist/src/lib/context/index.mjs +38 -73
- package/dist/src/lib/core.cjs +546 -231
- package/dist/src/lib/core.d.ts +3 -1
- package/dist/src/lib/core.d.ts.map +1 -1
- package/dist/src/lib/core.js +5 -3
- package/dist/src/lib/core.mjs +546 -222
- package/dist/src/lib/env/index.cjs +1 -17
- package/dist/src/lib/env/index.d.ts +2 -14
- package/dist/src/lib/env/index.d.ts.map +1 -1
- package/dist/src/lib/env/index.js +2 -26
- package/dist/src/lib/env/index.mjs +1 -17
- package/dist/src/lib/i18n/index.cjs +17 -2
- package/dist/src/lib/i18n/index.d.ts +10 -0
- package/dist/src/lib/i18n/index.d.ts.map +1 -1
- package/dist/src/lib/i18n/index.js +17 -1
- package/dist/src/lib/i18n/index.mjs +17 -2
- package/dist/src/lib/index.cjs +64 -99
- package/dist/src/lib/index.mjs +43 -76
- package/dist/src/lib/isomorphic.cjs +9 -4
- package/dist/src/lib/isomorphic.d.ts +9 -2
- package/dist/src/lib/isomorphic.d.ts.map +1 -1
- package/dist/src/lib/isomorphic.js +11 -4
- package/dist/src/lib/isomorphic.mjs +9 -4
- package/dist/src/lib/jsx-runtime/index.cjs +1 -1
- package/dist/src/lib/jsx-runtime/index.mjs +1 -1
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.cjs +1 -1
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.mjs +1 -1
- package/dist/src/lib/plugins/fluixi-routes-plugin.cjs +2 -2
- package/dist/src/lib/plugins/fluixi-routes-plugin.mjs +2 -2
- package/dist/src/lib/plugins/index.cjs +3 -3
- package/dist/src/lib/plugins/index.mjs +3 -3
- package/dist/src/lib/plugins/route-codegen.cjs +2 -2
- package/dist/src/lib/plugins/route-codegen.js +1 -1
- package/dist/src/lib/plugins/route-codegen.mjs +2 -2
- package/dist/src/lib/render/index.cjs +1 -1
- package/dist/src/lib/render/index.mjs +1 -1
- package/dist/src/lib/render/versions.cjs +1 -1
- package/dist/src/lib/render/versions.mjs +1 -1
- package/dist/src/lib/router/data.cjs +113 -115
- package/dist/src/lib/router/data.d.ts +63 -10
- package/dist/src/lib/router/data.d.ts.map +1 -1
- package/dist/src/lib/router/data.js +158 -68
- package/dist/src/lib/router/data.mjs +112 -112
- package/dist/src/lib/router/index.cjs +260 -163
- package/dist/src/lib/router/index.d.ts +22 -2
- package/dist/src/lib/router/index.d.ts.map +1 -1
- package/dist/src/lib/router/index.js +165 -22
- package/dist/src/lib/router/index.mjs +244 -143
- package/dist/src/lib/server/index.cjs +1 -1
- package/dist/src/lib/server/index.mjs +1 -1
- package/dist/src/lib/storage/cache.cjs +51 -0
- package/dist/src/lib/storage/cache.d.ts +18 -0
- package/dist/src/lib/storage/cache.d.ts.map +1 -0
- package/dist/src/lib/storage/cache.js +42 -0
- package/dist/src/lib/storage/cache.mjs +30 -0
- package/dist/src/lib/storage/index.cjs +246 -0
- package/dist/src/lib/storage/index.d.ts +83 -0
- package/dist/src/lib/storage/index.d.ts.map +1 -0
- package/dist/src/lib/storage/index.js +179 -0
- package/dist/src/lib/storage/index.mjs +231 -0
- package/dist/src/lib/storage/persisted.cjs +91 -0
- package/dist/src/lib/storage/persisted.d.ts +53 -0
- package/dist/src/lib/storage/persisted.d.ts.map +1 -0
- package/dist/src/lib/storage/persisted.js +75 -0
- package/dist/src/lib/storage/persisted.mjs +70 -0
- package/dist/src/lib/theme/color-scheme.cjs +281 -0
- package/dist/src/lib/theme/color-scheme.d.ts +61 -0
- package/dist/src/lib/theme/color-scheme.d.ts.map +1 -0
- package/dist/src/lib/theme/color-scheme.js +120 -0
- package/dist/src/lib/theme/color-scheme.mjs +265 -0
- package/dist/src/lib/theme/index.cjs +194 -37
- package/dist/src/lib/theme/index.d.ts +23 -11
- package/dist/src/lib/theme/index.d.ts.map +1 -1
- package/dist/src/lib/theme/index.js +73 -32
- package/dist/src/lib/theme/index.mjs +197 -35
- package/dist/src/lib/theme/provider.cjs +346 -0
- package/dist/src/lib/theme/provider.d.ts +34 -0
- package/dist/src/lib/theme/provider.d.ts.map +1 -0
- package/dist/src/lib/theme/provider.js +60 -0
- package/dist/src/lib/theme/provider.mjs +332 -0
- package/dist/src/routes.cjs +1 -1
- package/dist/src/routes.mjs +1 -1
- package/dist/src/utils.cjs +1 -1
- package/dist/src/utils.mjs +1 -1
- package/dist/src/version.generated.cjs +1 -1
- package/dist/src/version.generated.d.ts +1 -1
- package/dist/src/version.generated.js +1 -1
- package/dist/src/version.generated.mjs +1 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +18 -11
- package/dist/src/lib/client/chunk-SKXDXBGV.mjs +0 -133
package/dist/src/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @fluixi/core v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/core v1.0.0-alpha.93 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
"use strict";
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -24,6 +24,7 @@ __export(index_exports, {
|
|
|
24
24
|
$component: () => $component,
|
|
25
25
|
Await: () => Await,
|
|
26
26
|
ClientOnly: () => import_dom16.ClientOnly,
|
|
27
|
+
ColorSchemeProvider: () => ColorSchemeProvider,
|
|
27
28
|
Dynamic: () => import_dom16.Dynamic,
|
|
28
29
|
ErrorBoundary: () => import_dom16.ErrorBoundary,
|
|
29
30
|
FRAMEWORK_NAME: () => FRAMEWORK_NAME,
|
|
@@ -40,46 +41,45 @@ __export(index_exports, {
|
|
|
40
41
|
Suspense: () => Suspense,
|
|
41
42
|
SuspenseList: () => SuspenseList,
|
|
42
43
|
Switch: () => import_dom16.Switch,
|
|
44
|
+
ThemeProvider: () => ThemeProvider,
|
|
43
45
|
VERSION: () => VERSION,
|
|
44
46
|
addClass: () => import_dom18.addClass,
|
|
45
47
|
appendChildren: () => import_dom18.appendChildren,
|
|
46
|
-
batch: () =>
|
|
48
|
+
batch: () => import_signal18.batch,
|
|
47
49
|
classMap: () => import_dom19.classMap,
|
|
48
50
|
cleanupDelegation: () => cleanupDelegation,
|
|
49
51
|
clientOnly: () => clientOnly,
|
|
50
52
|
closest: () => import_dom18.closest,
|
|
51
53
|
composeProviders: () => composeProviders,
|
|
54
|
+
createColorScheme: () => createColorScheme,
|
|
52
55
|
createComponent: () => createComponent,
|
|
53
|
-
createComputed: () =>
|
|
54
|
-
createConsumer: () => createConsumer,
|
|
56
|
+
createComputed: () => import_signal18.createComputed,
|
|
55
57
|
createContext: () => createContext3,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
createEffect: () => import_signal15.createEffect,
|
|
58
|
+
createDebounce: () => import_signal19.createDebounce,
|
|
59
|
+
createDebouncedResource: () => import_signal19.createDebouncedResource,
|
|
60
|
+
createDebouncedSignal: () => import_signal19.createDebouncedSignal,
|
|
61
|
+
createDeferred: () => import_signal18.createDeferred,
|
|
62
|
+
createEffect: () => import_signal18.createEffect,
|
|
62
63
|
createIsomorphicState: () => createIsomorphicState,
|
|
63
64
|
createIsomorphicStore: () => createIsomorphicStore,
|
|
64
|
-
createMemo: () =>
|
|
65
|
-
createMemoryStorage: () => createMemoryStorage,
|
|
65
|
+
createMemo: () => import_signal18.createMemo,
|
|
66
66
|
createProvider: () => createProvider,
|
|
67
|
-
createRenderEffect: () =>
|
|
68
|
-
createResource: () =>
|
|
69
|
-
createRoot: () =>
|
|
70
|
-
createSelector: () =>
|
|
71
|
-
createSignal: () =>
|
|
67
|
+
createRenderEffect: () => import_signal18.createRenderEffect,
|
|
68
|
+
createResource: () => import_signal18.createResource,
|
|
69
|
+
createRoot: () => import_signal18.createRoot,
|
|
70
|
+
createSelector: () => import_signal19.createSelector,
|
|
71
|
+
createSignal: () => import_signal18.createSignal,
|
|
72
72
|
createStore: () => import_store.createStore,
|
|
73
73
|
createTheme: () => createTheme,
|
|
74
74
|
default: () => core_default,
|
|
75
75
|
deferred: () => deferred,
|
|
76
76
|
delegate: () => import_dom18.delegate,
|
|
77
77
|
domCreateElement: () => import_dom18.createElement,
|
|
78
|
-
effect: () =>
|
|
78
|
+
effect: () => import_signal18.effect,
|
|
79
79
|
env: () => env,
|
|
80
80
|
getAttribute: () => import_dom18.getAttribute,
|
|
81
81
|
getOffset: () => import_dom18.getOffset,
|
|
82
|
-
getOwner: () =>
|
|
82
|
+
getOwner: () => import_signal18.getOwner,
|
|
83
83
|
getStyle: () => import_dom18.getStyle,
|
|
84
84
|
hasClass: () => import_dom18.hasClass,
|
|
85
85
|
html: () => import_dom17.html,
|
|
@@ -93,11 +93,11 @@ __export(index_exports, {
|
|
|
93
93
|
isServer: () => import_dom12.isServer,
|
|
94
94
|
isVisible: () => import_dom18.isVisible,
|
|
95
95
|
lazy: () => lazy,
|
|
96
|
-
memo: () =>
|
|
96
|
+
memo: () => import_signal18.memo,
|
|
97
97
|
mergeProps: () => import_dom19.mergeProps,
|
|
98
98
|
observeIntersection: () => import_dom18.observeIntersection,
|
|
99
99
|
observeResize: () => import_dom18.observeResize,
|
|
100
|
-
onCleanup: () =>
|
|
100
|
+
onCleanup: () => import_signal18.onCleanup,
|
|
101
101
|
onMount: () => onMount,
|
|
102
102
|
onUnmount: () => onUnmount,
|
|
103
103
|
portal: () => portal,
|
|
@@ -109,22 +109,23 @@ __export(index_exports, {
|
|
|
109
109
|
removeChildren: () => import_dom18.removeChildren,
|
|
110
110
|
removeClass: () => import_dom18.removeClass,
|
|
111
111
|
render: () => render,
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
requireContext: () => requireContext,
|
|
113
|
+
resource: () => import_signal18.resource,
|
|
114
|
+
runWithOwner: () => import_signal18.runWithOwner,
|
|
114
115
|
scrollIntoView: () => import_dom18.scrollIntoView,
|
|
115
116
|
setAttribute: () => import_dom18.setAttribute,
|
|
116
|
-
setOwner: () =>
|
|
117
|
+
setOwner: () => import_signal18.setOwner,
|
|
117
118
|
setStyles: () => import_dom18.setStyles,
|
|
118
|
-
signal: () =>
|
|
119
|
+
signal: () => import_signal18.signal,
|
|
119
120
|
splitProps: () => import_dom19.splitProps,
|
|
120
|
-
storage: () => storage,
|
|
121
121
|
styleMap: () => import_dom19.styleMap,
|
|
122
122
|
svg: () => import_dom17.svg,
|
|
123
123
|
toggleClass: () => import_dom18.toggleClass,
|
|
124
|
-
untrack: () =>
|
|
124
|
+
untrack: () => import_signal18.untrack,
|
|
125
125
|
untrackStore: () => import_store.untrackStore,
|
|
126
126
|
unwrap: () => import_store.unwrap,
|
|
127
127
|
useCallback: () => useCallback,
|
|
128
|
+
useColorScheme: () => useColorScheme,
|
|
128
129
|
useContext: () => useContext3,
|
|
129
130
|
useEffect: () => useEffect,
|
|
130
131
|
useEventListener: () => useEventListener,
|
|
@@ -132,20 +133,20 @@ __export(index_exports, {
|
|
|
132
133
|
useMemo: () => useMemo,
|
|
133
134
|
useNavigate: () => useNavigate,
|
|
134
135
|
useParams: () => useParams,
|
|
135
|
-
useProvide: () => useProvide,
|
|
136
136
|
useReducer: () => useReducer,
|
|
137
137
|
useRef: () => useRef,
|
|
138
138
|
useRouter: () => useRouter,
|
|
139
|
+
useTheme: () => useTheme,
|
|
139
140
|
waitForElement: () => import_dom18.waitForElement
|
|
140
141
|
});
|
|
141
142
|
module.exports = __toCommonJS(index_exports);
|
|
142
143
|
|
|
143
144
|
// src/version.generated.ts
|
|
144
|
-
var VERSION = "1.0.0-alpha.
|
|
145
|
+
var VERSION = "1.0.0-alpha.93";
|
|
145
146
|
|
|
146
147
|
// src/lib/core.ts
|
|
147
|
-
var
|
|
148
|
-
var
|
|
148
|
+
var import_signal18 = require("@fluixi/reactive/signal");
|
|
149
|
+
var import_signal19 = require("@fluixi/reactive/signal");
|
|
149
150
|
var import_operators = require("@fluixi/reactive/operators");
|
|
150
151
|
|
|
151
152
|
// src/lib/render/index.ts
|
|
@@ -647,81 +648,20 @@ function cleanupDelegation() {
|
|
|
647
648
|
// src/lib/context/context.ts
|
|
648
649
|
var import_dom10 = require("@fluixi/dom");
|
|
649
650
|
var import_signal7 = require("@fluixi/reactive/signal");
|
|
650
|
-
var import_signal8 = require("@fluixi/reactive/signal");
|
|
651
|
-
var _warnedEagerProvider = false;
|
|
652
|
-
function warnEagerProvider() {
|
|
653
|
-
if (_warnedEagerProvider) return;
|
|
654
|
-
_warnedEagerProvider = true;
|
|
655
|
-
if (typeof process !== "undefined" && true) return;
|
|
656
|
-
console.warn(
|
|
657
|
-
"[fluixi] createProvider({ context, value, children }) reads `children` eagerly: the object literal materialises `children` BEFORE the context is stamped, so a routed <Outlet/> that has siblings inside the provider renders detached and its descendants see no context under SSR. Use the lazy form instead:\n createProvider(Context, value, props) // children stays a getter\n // or JSX: <Context.Provider value={...}>{props.children}</Context.Provider>"
|
|
658
|
-
);
|
|
659
|
-
}
|
|
660
|
-
function createProvider(a, value, childProps) {
|
|
661
|
-
const isLazyForm = !!a?.Provider;
|
|
662
|
-
const context = isLazyForm ? a : a.context;
|
|
663
|
-
const rawValue = isLazyForm ? value : a.value;
|
|
664
|
-
const debug = isLazyForm ? false : a.debug ?? false;
|
|
665
|
-
if (!isLazyForm) warnEagerProvider();
|
|
666
|
-
const resolvedValue = typeof rawValue === "function" ? rawValue() : rawValue;
|
|
667
|
-
const sourceProps = isLazyForm ? childProps : a;
|
|
668
|
-
return context.Provider({
|
|
669
|
-
value: resolvedValue,
|
|
670
|
-
get children() {
|
|
671
|
-
return sourceProps?.children;
|
|
672
|
-
},
|
|
673
|
-
debug
|
|
674
|
-
});
|
|
675
|
-
}
|
|
676
|
-
function createContextWithProvider(defaultValue) {
|
|
677
|
-
const context = createContext3(defaultValue);
|
|
678
|
-
const provider = (props) => {
|
|
679
|
-
return createProvider(context, props.value, props);
|
|
680
|
-
};
|
|
681
|
-
return [context, provider];
|
|
682
|
-
}
|
|
683
|
-
function composeProviders(contexts, children) {
|
|
684
|
-
if (contexts.length === 0) {
|
|
685
|
-
return (0, import_signal8.readChildren)(() => children);
|
|
686
|
-
}
|
|
687
|
-
const [context, value] = contexts[0];
|
|
688
|
-
const remaining = contexts.slice(1);
|
|
689
|
-
return createProvider(context, value, {
|
|
690
|
-
get children() {
|
|
691
|
-
return composeProviders(remaining, children);
|
|
692
|
-
}
|
|
693
|
-
});
|
|
694
|
-
}
|
|
695
|
-
function createConsumer(context) {
|
|
696
|
-
return (props) => {
|
|
697
|
-
const value = useContext3(context);
|
|
698
|
-
return props.children(value);
|
|
699
|
-
};
|
|
700
|
-
}
|
|
701
|
-
function useProvide(context, factory) {
|
|
702
|
-
const existing = useContext3(context);
|
|
703
|
-
if (existing === context.defaultValue) {
|
|
704
|
-
return factory();
|
|
705
|
-
}
|
|
706
|
-
return existing;
|
|
707
|
-
}
|
|
708
651
|
function createContext3(defaultValue, name) {
|
|
709
652
|
const context = (0, import_signal7.createContext)(defaultValue, name);
|
|
710
|
-
const Provider = (props) =>
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
653
|
+
const Provider = (props) => (
|
|
654
|
+
// Children stay a getter: the reactive Provider reads them after stamping the value on
|
|
655
|
+
// its owner. Reading `props.children` here would render them, and any <Outlet/> in them,
|
|
656
|
+
// before the context exists.
|
|
657
|
+
context.Provider({
|
|
714
658
|
value: props.value,
|
|
715
659
|
get children() {
|
|
716
660
|
return props.children;
|
|
717
661
|
},
|
|
718
662
|
debug: props.debug
|
|
719
|
-
})
|
|
720
|
-
|
|
721
|
-
if (typeof Symbol !== "undefined" && Symbol.for) {
|
|
722
|
-
Provider.$$typeof = /* @__PURE__ */ Symbol.for("react.provider");
|
|
723
|
-
}
|
|
724
|
-
Provider.$$typeof = /* @__PURE__ */ Symbol.for("react.provider");
|
|
663
|
+
})
|
|
664
|
+
);
|
|
725
665
|
return {
|
|
726
666
|
id: context.id,
|
|
727
667
|
Provider: (0, import_dom10.asProvider)(Provider),
|
|
@@ -732,10 +672,38 @@ function useContext3(context) {
|
|
|
732
672
|
const value = (0, import_signal7.useContext)(context);
|
|
733
673
|
return value !== void 0 ? value : context.defaultValue;
|
|
734
674
|
}
|
|
675
|
+
function createProvider(context, value, props) {
|
|
676
|
+
const resolved = typeof value === "function" ? value() : value;
|
|
677
|
+
return context.Provider({
|
|
678
|
+
value: resolved,
|
|
679
|
+
get children() {
|
|
680
|
+
return props.children;
|
|
681
|
+
}
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
function composeProviders(providers, props) {
|
|
685
|
+
const outermost = providers.reduceRight(
|
|
686
|
+
(inner, [context, value]) => ({
|
|
687
|
+
get children() {
|
|
688
|
+
return createProvider(context, value, inner);
|
|
689
|
+
}
|
|
690
|
+
}),
|
|
691
|
+
props
|
|
692
|
+
);
|
|
693
|
+
return outermost.children;
|
|
694
|
+
}
|
|
695
|
+
function requireContext(context, message) {
|
|
696
|
+
for (let owner = (0, import_signal7.getOwner)(); owner; owner = owner.parent) {
|
|
697
|
+
if (owner.contexts?.has(context.id)) return useContext3(context);
|
|
698
|
+
}
|
|
699
|
+
throw new Error(message ?? `[fluixi] No Provider for ${context.id.description ?? "this context"} above this component.`);
|
|
700
|
+
}
|
|
735
701
|
|
|
736
702
|
// src/lib/isomorphic.ts
|
|
737
|
-
var
|
|
703
|
+
var import_signal8 = require("@fluixi/reactive/signal");
|
|
738
704
|
var import_dom11 = require("@fluixi/dom");
|
|
705
|
+
var import_storage = require("@fluixi/storage");
|
|
706
|
+
var import_browser = require("@fluixi/storage/browser");
|
|
739
707
|
var REGISTRY_KEY = "__fluixi_iso_states__";
|
|
740
708
|
var SEED_PREFIX = "__iso:";
|
|
741
709
|
function registry() {
|
|
@@ -749,7 +717,7 @@ function readSeed(key) {
|
|
|
749
717
|
function createIsomorphicState(key, options) {
|
|
750
718
|
const seed = readSeed(key);
|
|
751
719
|
const initial = seed !== void 0 ? seed : typeof window !== "undefined" && options.client ? options.client() : options.fallback;
|
|
752
|
-
const [value, set] = (0,
|
|
720
|
+
const [value, set] = (0, import_signal8.createSignal)(initial, { name: key });
|
|
753
721
|
registry().set(key, { server: options.server, set });
|
|
754
722
|
return { value, set, key };
|
|
755
723
|
}
|
|
@@ -761,9 +729,12 @@ function createIsomorphicStore(key, options) {
|
|
|
761
729
|
});
|
|
762
730
|
const value = () => base.value() ?? options.fallback;
|
|
763
731
|
const persistWrite = (v) => {
|
|
764
|
-
|
|
732
|
+
const target = options.persist;
|
|
733
|
+
if (!target) return;
|
|
734
|
+
if (typeof target === "string" && typeof window === "undefined") return;
|
|
765
735
|
try {
|
|
766
|
-
|
|
736
|
+
const { storage, key: key2 } = typeof target === "string" ? { storage: (0, import_storage.createSyncStorage)({ adapter: (0, import_browser.localStorageAdapter)() }), key: target } : target;
|
|
737
|
+
storage.set(key2, v);
|
|
767
738
|
} catch {
|
|
768
739
|
}
|
|
769
740
|
};
|
|
@@ -776,7 +747,7 @@ function createIsomorphicStore(key, options) {
|
|
|
776
747
|
};
|
|
777
748
|
const fields = {};
|
|
778
749
|
for (const k of Object.keys(options.fallback)) {
|
|
779
|
-
fields[k] = (0,
|
|
750
|
+
fields[k] = (0, import_signal8.createMemo)(() => value()[k], void 0, { name: `${key}.${String(k)}` });
|
|
780
751
|
}
|
|
781
752
|
let initPromise = null;
|
|
782
753
|
const ensureInit = () => {
|
|
@@ -800,20 +771,6 @@ var import_dom13 = require("@fluixi/dom");
|
|
|
800
771
|
function isClient() {
|
|
801
772
|
return !(0, import_dom13.isServer)();
|
|
802
773
|
}
|
|
803
|
-
function createMemoryStorage() {
|
|
804
|
-
const mem = /* @__PURE__ */ new Map();
|
|
805
|
-
return {
|
|
806
|
-
getItem: (k) => mem.has(k) ? mem.get(k) : null,
|
|
807
|
-
setItem: (k, v) => void mem.set(k, String(v)),
|
|
808
|
-
removeItem: (k) => void mem.delete(k),
|
|
809
|
-
clear: () => mem.clear(),
|
|
810
|
-
key: (i) => Array.from(mem.keys())[i] ?? null,
|
|
811
|
-
get length() {
|
|
812
|
-
return mem.size;
|
|
813
|
-
}
|
|
814
|
-
};
|
|
815
|
-
}
|
|
816
|
-
var storage = typeof localStorage !== "undefined" ? localStorage : createMemoryStorage();
|
|
817
774
|
var env = {
|
|
818
775
|
get window() {
|
|
819
776
|
return typeof window !== "undefined" ? window : void 0;
|
|
@@ -827,36 +784,205 @@ function clientOnly(fn, fallback) {
|
|
|
827
784
|
}
|
|
828
785
|
|
|
829
786
|
// src/lib/theme/index.ts
|
|
787
|
+
var import_head = require("@fluixi/head");
|
|
788
|
+
var import_signal11 = require("@fluixi/reactive/signal");
|
|
789
|
+
var import_storage3 = require("@fluixi/storage");
|
|
790
|
+
|
|
791
|
+
// src/lib/storage/persisted.ts
|
|
792
|
+
var import_signal9 = require("@fluixi/reactive/signal");
|
|
793
|
+
var isAsync = (storage) => "encryption" in storage;
|
|
794
|
+
function persisted(storage, key, options = {}) {
|
|
795
|
+
const fallback = options.fallback ?? null;
|
|
796
|
+
const name = options.name ?? `storage:${storage.keyPrefix}${key}`;
|
|
797
|
+
const state = (0, import_signal9.signal)(isAsync(storage) ? fallback : storage.get(key) ?? fallback, { name });
|
|
798
|
+
const put = (value) => state.set(() => value);
|
|
799
|
+
const resolve = (next) => typeof next === "function" ? next((0, import_signal9.untrack)(state)) : next;
|
|
800
|
+
const writeOptions = (extra) => ({
|
|
801
|
+
...options.ttl !== void 0 ? { ttl: options.ttl } : {},
|
|
802
|
+
...options.encrypt ? { encrypt: true } : {},
|
|
803
|
+
...extra
|
|
804
|
+
});
|
|
805
|
+
if (!isAsync(storage)) {
|
|
806
|
+
const off2 = storage.subscribe(key, (event) => {
|
|
807
|
+
if (event.type !== "set") return put(fallback);
|
|
808
|
+
if (event.value !== void 0) put(event.value);
|
|
809
|
+
});
|
|
810
|
+
if ((0, import_signal9.getOwner)()) (0, import_signal9.onCleanup)(off2);
|
|
811
|
+
return Object.assign(() => state(), {
|
|
812
|
+
set(next, extra) {
|
|
813
|
+
const value = resolve(next);
|
|
814
|
+
storage.set(key, value, writeOptions(extra));
|
|
815
|
+
put(value);
|
|
816
|
+
},
|
|
817
|
+
remove() {
|
|
818
|
+
storage.remove(key);
|
|
819
|
+
put(fallback);
|
|
820
|
+
}
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
let written = false;
|
|
824
|
+
const reread = () => storage.get(key).then(
|
|
825
|
+
(value) => put(value ?? fallback),
|
|
826
|
+
() => void 0
|
|
827
|
+
);
|
|
828
|
+
const off = storage.subscribe(key, (event) => {
|
|
829
|
+
if (event.type !== "set") return put(fallback);
|
|
830
|
+
if (event.value !== void 0) put(event.value);
|
|
831
|
+
else void reread();
|
|
832
|
+
});
|
|
833
|
+
if ((0, import_signal9.getOwner)()) (0, import_signal9.onCleanup)(off);
|
|
834
|
+
const ready = storage.get(key).then((value) => {
|
|
835
|
+
if (!written) put(value ?? fallback);
|
|
836
|
+
});
|
|
837
|
+
return Object.assign(() => state(), {
|
|
838
|
+
ready,
|
|
839
|
+
async set(next, extra) {
|
|
840
|
+
const previous = (0, import_signal9.untrack)(state);
|
|
841
|
+
const value = resolve(next);
|
|
842
|
+
written = true;
|
|
843
|
+
put(value);
|
|
844
|
+
try {
|
|
845
|
+
await storage.set(key, value, writeOptions(extra));
|
|
846
|
+
} catch (error) {
|
|
847
|
+
put(previous);
|
|
848
|
+
throw error;
|
|
849
|
+
}
|
|
850
|
+
},
|
|
851
|
+
async remove() {
|
|
852
|
+
written = true;
|
|
853
|
+
await storage.remove(key);
|
|
854
|
+
put(fallback);
|
|
855
|
+
}
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
// src/lib/storage/index.ts
|
|
860
|
+
var import_dom14 = require("@fluixi/dom");
|
|
830
861
|
var import_signal10 = require("@fluixi/reactive/signal");
|
|
862
|
+
var import_storage2 = require("@fluixi/storage");
|
|
863
|
+
var import_browser2 = require("@fluixi/storage/browser");
|
|
864
|
+
var import_server = require("@fluixi/storage/server");
|
|
865
|
+
var StorageContext = (0, import_signal10.createContext)(void 0, "storage");
|
|
866
|
+
var AsyncStorageContext = (0, import_signal10.createContext)(void 0, "asyncStorage");
|
|
867
|
+
var isBrowser = () => typeof window !== "undefined" && typeof document !== "undefined";
|
|
868
|
+
var perRequest = /* @__PURE__ */ new WeakMap();
|
|
869
|
+
var perPage = /* @__PURE__ */ new Map();
|
|
870
|
+
function cached(scope, id, make) {
|
|
871
|
+
let adapter = scope.get(id);
|
|
872
|
+
if (!adapter) scope.set(id, adapter = make());
|
|
873
|
+
return adapter;
|
|
874
|
+
}
|
|
875
|
+
function requestRequired(scope) {
|
|
876
|
+
throw new import_storage2.StorageUnavailableError(
|
|
877
|
+
`useStorage({ scope: '${scope}' }) on the server needs a request: call it during a render, a loader or a server function, or provide a storage with <StorageProvider>.`
|
|
878
|
+
);
|
|
879
|
+
}
|
|
880
|
+
function adapterFor(scope, cookie = {}) {
|
|
881
|
+
const ctx = (0, import_dom14.getRequestContext)();
|
|
882
|
+
const options = { httpOnly: false, ...cookie };
|
|
883
|
+
switch (scope) {
|
|
884
|
+
case "local":
|
|
885
|
+
return (0, import_browser2.localStorageAdapter)();
|
|
886
|
+
case "session":
|
|
887
|
+
return (0, import_browser2.sessionStorageAdapter)();
|
|
888
|
+
case "request":
|
|
889
|
+
if (isBrowser()) return cached(perPage, "request", import_storage2.memoryStorage);
|
|
890
|
+
if (!ctx) requestRequired(scope);
|
|
891
|
+
return cached(perRequest.get(ctx) ?? perRequest.set(ctx, /* @__PURE__ */ new Map()).get(ctx), "request", import_server.requestStorage);
|
|
892
|
+
case "cookie": {
|
|
893
|
+
const id = `cookie:${JSON.stringify(options)}`;
|
|
894
|
+
if (isBrowser()) {
|
|
895
|
+
const { httpOnly: _ignored, ...browser } = options;
|
|
896
|
+
return cached(perPage, id, () => (0, import_browser2.documentCookieAdapter)(browser));
|
|
897
|
+
}
|
|
898
|
+
if (!ctx) requestRequired(scope);
|
|
899
|
+
const raw = ctx.event.request;
|
|
900
|
+
const target = raw && typeof raw === "object" ? raw : void 0;
|
|
901
|
+
return cached(
|
|
902
|
+
perRequest.get(ctx) ?? perRequest.set(ctx, /* @__PURE__ */ new Map()).get(ctx),
|
|
903
|
+
id,
|
|
904
|
+
() => (0, import_server.cookieStorage)({
|
|
905
|
+
...options,
|
|
906
|
+
request: raw && typeof raw === "object" && ("headers" in raw || "getHeader" in raw) ? (0, import_server.toStorageRequest)(raw) : void 0,
|
|
907
|
+
response: {
|
|
908
|
+
appendHeader(name, value) {
|
|
909
|
+
if (!(0, import_dom14.appendResponseHeader)(name, value, target)) {
|
|
910
|
+
throw new import_storage2.StorageUnavailableError("The response headers were already sent, so this cookie cannot reach the browser. Write it before the page head goes out: in middleware, a loader, a server function or the render before its first chunk.");
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
})
|
|
915
|
+
);
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
function useStorage(options = {}) {
|
|
920
|
+
const { scope = "auto", cookie, ...storageOptions } = options;
|
|
921
|
+
if (scope === "auto") {
|
|
922
|
+
const provided = (0, import_signal10.useContext)(StorageContext);
|
|
923
|
+
if (provided) return options.namespace ? provided.namespace(options.namespace) : provided;
|
|
924
|
+
}
|
|
925
|
+
return (0, import_storage2.createSyncStorage)({ ...storageOptions, adapter: resolveAdapter(scope, cookie) });
|
|
926
|
+
}
|
|
927
|
+
function resolveAdapter(scope, cookie) {
|
|
928
|
+
if (scope !== "auto") return adapterFor(scope, cookie);
|
|
929
|
+
if (isBrowser()) return adapterFor("local");
|
|
930
|
+
if (!(0, import_dom14.getRequestContext)()) requestRequired(scope);
|
|
931
|
+
return adapterFor("request");
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
// src/lib/theme/index.ts
|
|
831
935
|
function systemMap(system) {
|
|
832
936
|
if (!system) return null;
|
|
833
937
|
if (system === true) return { dark: "dark", light: "light" };
|
|
834
938
|
return system;
|
|
835
939
|
}
|
|
940
|
+
var YEAR = 60 * 60 * 24 * 365;
|
|
941
|
+
function defaultStorage() {
|
|
942
|
+
try {
|
|
943
|
+
return useStorage({ scope: "cookie", cookie: { maxAge: YEAR, sameSite: "lax" } });
|
|
944
|
+
} catch (error) {
|
|
945
|
+
if (error instanceof import_storage3.StorageUnavailableError) return null;
|
|
946
|
+
throw error;
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
function storedLookup(storage, key) {
|
|
950
|
+
if (!storage) return null;
|
|
951
|
+
const full = storage.keyPrefix + key;
|
|
952
|
+
if (storage.scope === "cookie") {
|
|
953
|
+
return { from: "cookie", name: encodeURIComponent(full).replace(/[()]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`) };
|
|
954
|
+
}
|
|
955
|
+
if (storage.scope === "local") return { from: "local", name: full };
|
|
956
|
+
return null;
|
|
957
|
+
}
|
|
836
958
|
function createTheme(options) {
|
|
837
959
|
const storageKey = options.storageKey ?? "theme";
|
|
838
960
|
const attribute = options.attribute ?? "data-theme";
|
|
839
961
|
const sys = systemMap(options.system);
|
|
840
|
-
const
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
962
|
+
const storage = options.storage === void 0 ? defaultStorage() : options.storage;
|
|
963
|
+
const valid = (t) => typeof t === "string" && options.themes.includes(t);
|
|
964
|
+
const fallback = sys && env.window?.matchMedia?.("(prefers-color-scheme: dark)")?.matches ? sys.dark : sys ? sys.light : options.default;
|
|
965
|
+
const stored = storage ? persisted(storage, storageKey) : null;
|
|
966
|
+
const [unsaved, setUnsaved] = (0, import_signal11.createSignal)(null);
|
|
967
|
+
const value = () => {
|
|
968
|
+
const local = unsaved();
|
|
969
|
+
if (local !== null) return local;
|
|
970
|
+
const saved = stored?.();
|
|
971
|
+
return valid(saved) ? saved : fallback;
|
|
846
972
|
};
|
|
847
|
-
const [
|
|
848
|
-
const [isLoading, setLoading] = (0, import_signal10.createSignal)(false);
|
|
973
|
+
const [isLoading, setLoading] = (0, import_signal11.createSignal)(false);
|
|
849
974
|
const apply = (t) => {
|
|
850
975
|
env.document?.documentElement.setAttribute(attribute, t);
|
|
851
|
-
try {
|
|
852
|
-
storage.setItem(storageKey, t);
|
|
853
|
-
} catch {
|
|
854
|
-
}
|
|
855
976
|
};
|
|
856
977
|
const set = (t) => {
|
|
857
978
|
if (!options.themes.includes(t)) return;
|
|
858
979
|
const prev = value();
|
|
859
|
-
|
|
980
|
+
try {
|
|
981
|
+
stored?.set(t);
|
|
982
|
+
setUnsaved(stored ? null : t);
|
|
983
|
+
} catch {
|
|
984
|
+
setUnsaved(() => t);
|
|
985
|
+
}
|
|
860
986
|
apply(t);
|
|
861
987
|
options.onChange?.(t, prev);
|
|
862
988
|
if (options.load) {
|
|
@@ -873,20 +999,130 @@ function createTheme(options) {
|
|
|
873
999
|
set(options.themes[(i + 1) % options.themes.length]);
|
|
874
1000
|
};
|
|
875
1001
|
const init = () => apply(value());
|
|
876
|
-
const
|
|
877
|
-
const cfg = JSON.stringify({
|
|
878
|
-
|
|
879
|
-
a: attribute,
|
|
880
|
-
d: options.default,
|
|
881
|
-
sys
|
|
882
|
-
});
|
|
883
|
-
return `<script>(function(){try{var c=${cfg},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>`;
|
|
1002
|
+
const scriptBody = () => {
|
|
1003
|
+
const cfg = JSON.stringify({ s: storedLookup(storage, storageKey), a: attribute, d: options.default, sys, ts: options.themes }).replace(/</g, "\\u003c");
|
|
1004
|
+
return `(function(){try{var c=${cfg},t=null,s=c.s,r=null;if(s&&s.from==='local')r=localStorage.getItem(s.name);if(s&&s.from==='cookie')document.cookie.split('; ').forEach(function(p){var i=p.indexOf('=');if(p.slice(0,i)===s.name)r=decodeURIComponent(p.slice(i+1));});if(r){var e=JSON.parse(r);t=e&&e.v===1?e.value:e;}if(c.ts.indexOf(t)<0)t=null;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){}})();`;
|
|
884
1005
|
};
|
|
1006
|
+
const headScript = () => `<script>${scriptBody()}<\/script>`;
|
|
1007
|
+
if ((0, import_head.getActiveHead)()) {
|
|
1008
|
+
(0, import_head.useHead)({
|
|
1009
|
+
htmlAttrs: { [attribute]: () => value() },
|
|
1010
|
+
...options.script === false ? {} : { script: [{ children: scriptBody() }] }
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
885
1013
|
return { value, isLoading, set, toggle, init, headScript };
|
|
886
1014
|
}
|
|
887
1015
|
|
|
888
|
-
// src/lib/
|
|
1016
|
+
// src/lib/theme/color-scheme.ts
|
|
1017
|
+
var import_head2 = require("@fluixi/head");
|
|
889
1018
|
var import_signal12 = require("@fluixi/reactive/signal");
|
|
1019
|
+
var CHOICES = ["system", "light", "dark"];
|
|
1020
|
+
var DARK = "(prefers-color-scheme: dark)";
|
|
1021
|
+
function createColorScheme(options = {}) {
|
|
1022
|
+
const storageKey = options.storageKey ?? "color-scheme";
|
|
1023
|
+
const attribute = options.attribute ?? "data-theme";
|
|
1024
|
+
const systemAs = options.systemAs ?? "resolved";
|
|
1025
|
+
const storage = options.storage === void 0 ? defaultStorage() : options.storage;
|
|
1026
|
+
const saved = storage ? persisted(storage, storageKey) : null;
|
|
1027
|
+
const [unsaved, setUnsaved] = (0, import_signal12.createSignal)(null);
|
|
1028
|
+
const value = () => {
|
|
1029
|
+
const local = unsaved();
|
|
1030
|
+
if (local) return local;
|
|
1031
|
+
const stored = saved?.();
|
|
1032
|
+
return CHOICES.includes(stored) ? stored : "system";
|
|
1033
|
+
};
|
|
1034
|
+
const media = env.window?.matchMedia?.(DARK);
|
|
1035
|
+
const [osDark, setOsDark] = (0, import_signal12.createSignal)(media?.matches ?? false);
|
|
1036
|
+
if (media) {
|
|
1037
|
+
const onChange = () => setOsDark(media.matches);
|
|
1038
|
+
media.addEventListener?.("change", onChange);
|
|
1039
|
+
if ((0, import_signal12.getOwner)()) (0, import_signal12.onCleanup)(() => media.removeEventListener?.("change", onChange));
|
|
1040
|
+
}
|
|
1041
|
+
const resolved = () => {
|
|
1042
|
+
const choice = value();
|
|
1043
|
+
return choice === "system" ? osDark() ? "dark" : "light" : choice;
|
|
1044
|
+
};
|
|
1045
|
+
const shown = () => systemAs === "system" && value() === "system" ? "system" : resolved();
|
|
1046
|
+
const apply = () => {
|
|
1047
|
+
env.document?.documentElement.setAttribute(attribute, shown());
|
|
1048
|
+
};
|
|
1049
|
+
const set = (choice) => {
|
|
1050
|
+
if (!CHOICES.includes(choice)) return;
|
|
1051
|
+
if (!saved) setUnsaved(choice);
|
|
1052
|
+
else {
|
|
1053
|
+
try {
|
|
1054
|
+
saved.set(choice);
|
|
1055
|
+
setUnsaved(null);
|
|
1056
|
+
} catch {
|
|
1057
|
+
setUnsaved(choice);
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
apply();
|
|
1061
|
+
options.onChange?.(choice);
|
|
1062
|
+
};
|
|
1063
|
+
const scriptBody = () => {
|
|
1064
|
+
const cfg = JSON.stringify({ s: storedLookup(storage, storageKey), a: attribute, sys: systemAs === "system", tc: options.themeColor ?? null, cs: options.colorSchemeMeta !== false }).replace(/</g, "\\u003c");
|
|
1065
|
+
return `(function(){try{var c=${cfg},t=null,s=c.s,r=null;if(s&&s.from==='local')r=localStorage.getItem(s.name);if(s&&s.from==='cookie')document.cookie.split('; ').forEach(function(p){var i=p.indexOf('=');if(p.slice(0,i)===s.name)r=decodeURIComponent(p.slice(i+1));});if(r){var e=JSON.parse(r);t=e&&e.v===1?e.value:e;}var chosen=t==='light'||t==='dark'?t:null;if(!chosen)t=c.sys?'system':(matchMedia('${DARK}').matches?'dark':'light');document.documentElement.setAttribute(c.a,t);if(chosen&&c.tc)document.querySelectorAll('meta[name="theme-color"]').forEach(function(m){m.setAttribute('content',c.tc[chosen]);m.removeAttribute('media');});if(chosen&&c.cs){var m=document.querySelector('meta[name="color-scheme"]');if(m)m.setAttribute('content',chosen);}}catch(e){}})();`;
|
|
1066
|
+
};
|
|
1067
|
+
if ((0, import_head2.getActiveHead)()) {
|
|
1068
|
+
const colors = options.themeColor;
|
|
1069
|
+
(0, import_head2.useHead)({
|
|
1070
|
+
htmlAttrs: { [attribute]: shown },
|
|
1071
|
+
...colors ? {
|
|
1072
|
+
themeColor: () => value() === "system" ? [
|
|
1073
|
+
{ color: colors.light, media: "(prefers-color-scheme: light)" },
|
|
1074
|
+
{ color: colors.dark, media: DARK }
|
|
1075
|
+
] : colors[resolved()]
|
|
1076
|
+
} : {},
|
|
1077
|
+
...options.colorSchemeMeta === false ? {} : { colorScheme: () => value() === "system" ? "light dark" : resolved() },
|
|
1078
|
+
...options.script === false ? {} : { script: [{ children: scriptBody() }] }
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
1081
|
+
if (env.document && (0, import_signal12.getOwner)()) (0, import_signal12.createEffect)(apply);
|
|
1082
|
+
return {
|
|
1083
|
+
value,
|
|
1084
|
+
resolved,
|
|
1085
|
+
set,
|
|
1086
|
+
toggle: () => set(resolved() === "dark" ? "light" : "dark"),
|
|
1087
|
+
init: apply,
|
|
1088
|
+
headScript: () => `<script>${scriptBody()}<\/script>`
|
|
1089
|
+
};
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
// src/lib/theme/provider.ts
|
|
1093
|
+
var ThemesContext = createContext3(void 0, "themes");
|
|
1094
|
+
function ThemeProvider(props) {
|
|
1095
|
+
const outer = useContext3(ThemesContext);
|
|
1096
|
+
return ThemesContext.Provider({
|
|
1097
|
+
// A nested provider adds to the axes above it rather than hiding them.
|
|
1098
|
+
value: outer ? { ...outer, ...props.themes } : props.themes,
|
|
1099
|
+
get children() {
|
|
1100
|
+
return props.children;
|
|
1101
|
+
}
|
|
1102
|
+
});
|
|
1103
|
+
}
|
|
1104
|
+
function useTheme(name) {
|
|
1105
|
+
const themes = useContext3(ThemesContext);
|
|
1106
|
+
if (!themes || !(name in themes)) {
|
|
1107
|
+
throw new Error(`[fluixi] No theme named "${name}" above this component: provide it with <ThemeProvider> or <ColorSchemeProvider>.`);
|
|
1108
|
+
}
|
|
1109
|
+
return themes[name];
|
|
1110
|
+
}
|
|
1111
|
+
function ColorSchemeProvider(props) {
|
|
1112
|
+
const scheme = createColorScheme(props);
|
|
1113
|
+
return ThemeProvider({
|
|
1114
|
+
themes: { scheme },
|
|
1115
|
+
get children() {
|
|
1116
|
+
return props.children;
|
|
1117
|
+
}
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1120
|
+
function useColorScheme() {
|
|
1121
|
+
return useTheme("scheme");
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
// src/lib/router/index.ts
|
|
1125
|
+
var import_signal15 = require("@fluixi/reactive/signal");
|
|
890
1126
|
|
|
891
1127
|
// src/lib/router/transition.ts
|
|
892
1128
|
function supportsViewTransitions() {
|
|
@@ -938,76 +1174,95 @@ function runTransition(mode, commit) {
|
|
|
938
1174
|
|
|
939
1175
|
// src/lib/router/index.ts
|
|
940
1176
|
var import_dom15 = require("@fluixi/dom");
|
|
941
|
-
var
|
|
1177
|
+
var import_signal16 = require("@fluixi/reactive/signal");
|
|
942
1178
|
var import_object = require("@fluixi/utils/object");
|
|
943
1179
|
var import_compare = require("@fluixi/utils/compare");
|
|
944
1180
|
var import_router = require("@fluixi/router");
|
|
945
|
-
var import_router2 = require("@fluixi/router");
|
|
946
1181
|
|
|
947
1182
|
// src/lib/router/data.ts
|
|
948
|
-
var
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
hydrationDataMap.clear();
|
|
1183
|
+
var import_signal13 = require("@fluixi/reactive/signal");
|
|
1184
|
+
var import_signal14 = require("@fluixi/reactive/signal");
|
|
1185
|
+
var revalidationListeners = /* @__PURE__ */ new Set();
|
|
1186
|
+
function onRevalidate(listener) {
|
|
1187
|
+
revalidationListeners.add(listener);
|
|
1188
|
+
return () => void revalidationListeners.delete(listener);
|
|
955
1189
|
}
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
const
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
if (text.startsWith("#") || text.startsWith("/")) {
|
|
975
|
-
comments.push(comment);
|
|
976
|
-
}
|
|
1190
|
+
var reloadMounted = () => {
|
|
1191
|
+
for (const listener of [...revalidationListeners]) listener();
|
|
1192
|
+
};
|
|
1193
|
+
function revalidate(key, store) {
|
|
1194
|
+
const names = typeof key === "string" ? [key] : Array.isArray(key) ? key : null;
|
|
1195
|
+
drop(names ?? key, store ?? (0, import_signal14.currentResourceCache)());
|
|
1196
|
+
if (names && !store) tellOtherTabs(names);
|
|
1197
|
+
}
|
|
1198
|
+
function drop(what, store) {
|
|
1199
|
+
const matches = Array.isArray(what) ? (k) => what.some((n) => k === n || k.startsWith(n + ":")) : what;
|
|
1200
|
+
for (const k of [...store.keys()]) if (matches(k)) store.delete(k);
|
|
1201
|
+
reloadMounted();
|
|
1202
|
+
}
|
|
1203
|
+
var TABS_KEY = "fluixi:revalidate";
|
|
1204
|
+
function tellOtherTabs(names) {
|
|
1205
|
+
try {
|
|
1206
|
+
localStorage.setItem(TABS_KEY, JSON.stringify({ names, at: Date.now() + Math.random() }));
|
|
1207
|
+
} catch {
|
|
977
1208
|
}
|
|
978
|
-
comments.forEach((comment) => comment.remove());
|
|
979
|
-
clearHydrationData();
|
|
980
1209
|
}
|
|
981
1210
|
if (typeof window !== "undefined") {
|
|
982
|
-
window.addEventListener("
|
|
983
|
-
|
|
1211
|
+
window.addEventListener("storage", (event) => {
|
|
1212
|
+
if (event.key !== TABS_KEY || !event.newValue) return;
|
|
1213
|
+
try {
|
|
1214
|
+
const names = JSON.parse(event.newValue).names;
|
|
1215
|
+
if (Array.isArray(names) && names.every((n) => typeof n === "string")) drop(names, (0, import_signal14.currentResourceCache)());
|
|
1216
|
+
} catch {
|
|
1217
|
+
}
|
|
984
1218
|
});
|
|
985
1219
|
}
|
|
986
|
-
|
|
987
|
-
// src/lib/router/data.ts
|
|
988
|
-
var [revalidationVersion, setRevalidationVersion] = (0, import_signal11.createSignal)(0);
|
|
1220
|
+
globalThis[/* @__PURE__ */ Symbol.for("fluixi.revalidate")] = (names) => revalidate(names);
|
|
989
1221
|
var RouteDataContext = createContext3(void 0, "route-data");
|
|
990
1222
|
var RouteDataProvider = RouteDataContext.Provider;
|
|
991
1223
|
|
|
992
1224
|
// src/lib/router/index.ts
|
|
993
|
-
var
|
|
994
|
-
var
|
|
995
|
-
var
|
|
996
|
-
var
|
|
997
|
-
var
|
|
1225
|
+
var import_router2 = require("@fluixi/router");
|
|
1226
|
+
var import_signal17 = require("@fluixi/reactive/signal");
|
|
1227
|
+
var RouterContext = (0, import_signal16.createContext)(void 0, "router");
|
|
1228
|
+
var OutletContext = (0, import_signal16.createContext)(void 0, "outlet");
|
|
1229
|
+
var LevelParamsContext = (0, import_signal16.createContext)(void 0, "route-params");
|
|
1230
|
+
var RouteDataContext2 = (0, import_signal16.createContext)(void 0, "route-data");
|
|
998
1231
|
function renderLayer(m, depth, base) {
|
|
999
1232
|
let data;
|
|
1000
1233
|
const loader = m.route.data;
|
|
1001
1234
|
if (typeof loader === "function") {
|
|
1002
1235
|
let cancelled = false;
|
|
1003
|
-
(0,
|
|
1236
|
+
(0, import_signal15.onCleanup)(() => {
|
|
1004
1237
|
cancelled = true;
|
|
1005
1238
|
});
|
|
1006
|
-
const owner = (0,
|
|
1007
|
-
const
|
|
1008
|
-
|
|
1009
|
-
)
|
|
1010
|
-
|
|
1239
|
+
const owner = (0, import_signal15.getOwner)();
|
|
1240
|
+
const router = (0, import_signal16.useContext)(RouterContext);
|
|
1241
|
+
let watching = false;
|
|
1242
|
+
const trackDeps = (deps) => {
|
|
1243
|
+
if (watching || cancelled) return;
|
|
1244
|
+
watching = true;
|
|
1245
|
+
(0, import_signal15.runWithOwner)(owner, () => {
|
|
1246
|
+
let first = true;
|
|
1247
|
+
(0, import_signal15.createEffect)(() => {
|
|
1248
|
+
deps();
|
|
1249
|
+
if (first) first = false;
|
|
1250
|
+
else (0, import_signal15.untrack)(() => void refetch());
|
|
1251
|
+
});
|
|
1252
|
+
});
|
|
1253
|
+
};
|
|
1254
|
+
const [resource2, { refetch }] = (0, import_signal15.createResource)(() => {
|
|
1255
|
+
const result = loader({ params: base.params, location: base.location }, owner, () => cancelled, trackDeps);
|
|
1256
|
+
return router ? router.trackLoad(result) : result;
|
|
1257
|
+
});
|
|
1258
|
+
(0, import_signal15.onCleanup)(onRevalidate(() => void refetch()));
|
|
1259
|
+
data = () => {
|
|
1260
|
+
const error = resource2.error;
|
|
1261
|
+
if (error !== void 0 && error !== null) throw error;
|
|
1262
|
+
return resource2();
|
|
1263
|
+
};
|
|
1264
|
+
Object.defineProperty(data, "loading", { get: () => resource2.loading });
|
|
1265
|
+
Object.defineProperty(data, "state", { get: () => resource2.state });
|
|
1011
1266
|
}
|
|
1012
1267
|
const buildPage = () => RouteDataContext2.Provider({
|
|
1013
1268
|
value: data,
|
|
@@ -1025,33 +1280,62 @@ function renderLayer(m, depth, base) {
|
|
|
1025
1280
|
});
|
|
1026
1281
|
}
|
|
1027
1282
|
});
|
|
1028
|
-
if (!data) return buildPage();
|
|
1283
|
+
if (!data) return { view: buildPage(), ready: () => true };
|
|
1029
1284
|
const res = data;
|
|
1030
|
-
const isLoading = () =>
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1285
|
+
const isLoading = () => {
|
|
1286
|
+
const state = res.state;
|
|
1287
|
+
return state === void 0 ? res.loading : state === "pending" || state === "unresolved";
|
|
1288
|
+
};
|
|
1289
|
+
const [ready, setReady] = (0, import_signal15.createSignal)((0, import_signal15.untrack)(() => !isLoading()));
|
|
1290
|
+
(0, import_signal15.createEffect)(() => setReady(!isLoading()));
|
|
1291
|
+
return { view: (0, import_signal15.createMemo)(() => ready() ? buildPage() : null), ready };
|
|
1034
1292
|
}
|
|
1035
1293
|
function renderChild(ctx) {
|
|
1036
1294
|
const childIdx = ctx.depth + 1;
|
|
1037
|
-
const [childComp, setChildComp] = (0,
|
|
1038
|
-
(0,
|
|
1295
|
+
const [childComp, setChildComp] = (0, import_signal15.createSignal)(
|
|
1296
|
+
(0, import_signal15.untrack)(() => ctx.matched()[childIdx]?.component)
|
|
1039
1297
|
);
|
|
1040
|
-
(0,
|
|
1298
|
+
(0, import_signal15.createEffect)(() => {
|
|
1041
1299
|
const c = ctx.matched()[childIdx]?.component;
|
|
1042
|
-
if ((0,
|
|
1300
|
+
if ((0, import_signal15.untrack)(childComp) !== c) setChildComp(() => c);
|
|
1043
1301
|
});
|
|
1044
|
-
|
|
1302
|
+
const owner = (0, import_signal15.getOwner)();
|
|
1303
|
+
let shown = null;
|
|
1304
|
+
let pending = null;
|
|
1305
|
+
const drop2 = (layer) => layer?.dispose();
|
|
1306
|
+
(0, import_signal15.onCleanup)(() => {
|
|
1307
|
+
drop2(shown);
|
|
1308
|
+
drop2(pending);
|
|
1309
|
+
shown = pending = null;
|
|
1310
|
+
});
|
|
1311
|
+
const incoming = (0, import_signal15.createMemo)(() => {
|
|
1045
1312
|
const component = childComp();
|
|
1046
|
-
if (!component)
|
|
1313
|
+
if (!component) return null;
|
|
1314
|
+
const m = (0, import_signal15.untrack)(() => ctx.matched())[childIdx];
|
|
1315
|
+
return (0, import_signal15.runWithOwner)(
|
|
1316
|
+
owner,
|
|
1317
|
+
() => (0, import_signal15.createRoot)((dispose) => ({
|
|
1318
|
+
...renderLayer(m, childIdx, { matched: ctx.matched, params: ctx.params, location: ctx.location }),
|
|
1319
|
+
dispose
|
|
1320
|
+
}))
|
|
1321
|
+
);
|
|
1322
|
+
});
|
|
1323
|
+
return (0, import_signal15.createMemo)(() => {
|
|
1324
|
+
const next = incoming();
|
|
1325
|
+
if (!next) {
|
|
1326
|
+
drop2(shown);
|
|
1327
|
+
drop2(pending);
|
|
1328
|
+
shown = pending = null;
|
|
1047
1329
|
return ctx.notFound ? ctx.notFound() : null;
|
|
1048
1330
|
}
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1331
|
+
if (next === shown) return shown.view;
|
|
1332
|
+
if (pending && pending !== next) drop2(pending);
|
|
1333
|
+
pending = next;
|
|
1334
|
+
if (shown && !next.ready()) return shown.view;
|
|
1335
|
+
drop2(shown);
|
|
1336
|
+
shown = next;
|
|
1337
|
+
pending = null;
|
|
1338
|
+
return shown.view;
|
|
1055
1339
|
});
|
|
1056
1340
|
}
|
|
1057
1341
|
function renderNotFound(notFound) {
|
|
@@ -1085,7 +1369,9 @@ function Router(props) {
|
|
|
1085
1369
|
base: props.base,
|
|
1086
1370
|
history
|
|
1087
1371
|
});
|
|
1088
|
-
const [state, setState] = (0,
|
|
1372
|
+
const [state, setState] = (0, import_signal15.createSignal)(router.state());
|
|
1373
|
+
const [navigating, setNavigating] = (0, import_signal15.createSignal)(false);
|
|
1374
|
+
const [loads, setLoads] = (0, import_signal15.createSignal)(0);
|
|
1089
1375
|
let navigationId = 0;
|
|
1090
1376
|
const takeMode = () => {
|
|
1091
1377
|
const mode = pendingTransitionMode ?? (props.transition ?? "auto");
|
|
@@ -1095,12 +1381,15 @@ function Router(props) {
|
|
|
1095
1381
|
const unsub = router.subscribe((next) => {
|
|
1096
1382
|
const id = ++navigationId;
|
|
1097
1383
|
const mode = takeMode();
|
|
1384
|
+
setNavigating(true);
|
|
1098
1385
|
const prepared = prepareComponents(
|
|
1099
1386
|
(next.match?.matched ?? []).map((m) => m.component).filter(Boolean)
|
|
1100
1387
|
);
|
|
1101
1388
|
const commit = () => {
|
|
1102
1389
|
setState(next);
|
|
1103
|
-
|
|
1390
|
+
const flushed = (0, import_signal15.flush)();
|
|
1391
|
+
if (id === navigationId) setNavigating(false);
|
|
1392
|
+
return flushed;
|
|
1104
1393
|
};
|
|
1105
1394
|
if (!prepared) {
|
|
1106
1395
|
void runTransition(mode, commit);
|
|
@@ -1111,18 +1400,29 @@ function Router(props) {
|
|
|
1111
1400
|
return runTransition(mode, commit);
|
|
1112
1401
|
});
|
|
1113
1402
|
});
|
|
1114
|
-
(0,
|
|
1403
|
+
(0, import_signal15.onCleanup)(() => {
|
|
1115
1404
|
unsub();
|
|
1116
1405
|
router.destroy();
|
|
1117
1406
|
navigationId++;
|
|
1118
1407
|
});
|
|
1119
|
-
const matched = (0,
|
|
1408
|
+
const matched = (0, import_signal15.createMemo)(
|
|
1120
1409
|
() => (state().match?.matched ?? []).filter((m) => m.component)
|
|
1121
1410
|
);
|
|
1122
1411
|
const ctx = {
|
|
1123
1412
|
router,
|
|
1124
|
-
location: (0,
|
|
1125
|
-
params: (0,
|
|
1413
|
+
location: (0, import_signal15.createMemo)(() => state().location),
|
|
1414
|
+
params: (0, import_signal15.createMemo)(() => state().match?.params ?? {}),
|
|
1415
|
+
isRouting: () => navigating() || loads() > 0,
|
|
1416
|
+
// Counted by the promise, not by an owner: a load a newer navigation superseded still
|
|
1417
|
+
// settles and uncounts itself, and a resource seeded from the server never calls it.
|
|
1418
|
+
trackLoad(result) {
|
|
1419
|
+
if (result && typeof result.finally === "function") {
|
|
1420
|
+
setLoads((n) => n + 1);
|
|
1421
|
+
void result.finally(() => setLoads((n) => n - 1)).catch(() => {
|
|
1422
|
+
});
|
|
1423
|
+
}
|
|
1424
|
+
return result;
|
|
1425
|
+
}
|
|
1126
1426
|
};
|
|
1127
1427
|
const root = {
|
|
1128
1428
|
depth: -1,
|
|
@@ -1144,17 +1444,19 @@ var _ssrRouterStub = {
|
|
|
1144
1444
|
router: { navigate: () => {
|
|
1145
1445
|
} },
|
|
1146
1446
|
location: () => ({ pathname: "", search: "", hash: "", query: {} }),
|
|
1147
|
-
params: () => ({})
|
|
1447
|
+
params: () => ({}),
|
|
1448
|
+
isRouting: () => false,
|
|
1449
|
+
trackLoad: (result) => result
|
|
1148
1450
|
};
|
|
1149
1451
|
function useRouter() {
|
|
1150
|
-
const ctx = (0,
|
|
1452
|
+
const ctx = (0, import_signal16.useContext)(RouterContext);
|
|
1151
1453
|
if (ctx) return ctx;
|
|
1152
1454
|
if (typeof window === "undefined") return _ssrRouterStub;
|
|
1153
1455
|
throw new Error("[router] useRouter must be used within <Router>");
|
|
1154
1456
|
}
|
|
1155
1457
|
function useParams() {
|
|
1156
1458
|
const params = useRouter().params;
|
|
1157
|
-
return (0,
|
|
1459
|
+
return (0, import_signal15.createMemo)(() => params(), {}, {
|
|
1158
1460
|
equals: (a, b) => JSON.stringify(a) === JSON.stringify(b)
|
|
1159
1461
|
});
|
|
1160
1462
|
}
|
|
@@ -1186,19 +1488,32 @@ var LINK_OWN_PROPS = /* @__PURE__ */ new Set([
|
|
|
1186
1488
|
"children"
|
|
1187
1489
|
]);
|
|
1188
1490
|
function Link(props) {
|
|
1189
|
-
const ctx = (0,
|
|
1190
|
-
const navigate = () => ctx
|
|
1491
|
+
const ctx = (0, import_signal16.useContext)(RouterContext);
|
|
1492
|
+
const navigate = () => ctx.router.navigate(read(props.href) ?? "", { replace: read(props.replace) });
|
|
1191
1493
|
const a = (0, import_dom15.createNativeElement)("a");
|
|
1192
1494
|
(0, import_dom15.setAttribute)(a, "href", read(props.href) ?? "");
|
|
1193
1495
|
if (props.slot) (0, import_dom15.setAttribute)(a, "slot", read(props.slot));
|
|
1194
1496
|
for (const k of Object.keys(props)) {
|
|
1195
1497
|
if (LINK_OWN_PROPS.has(k)) continue;
|
|
1196
1498
|
const v = props[k];
|
|
1197
|
-
if (
|
|
1499
|
+
if (typeof v === "function") {
|
|
1500
|
+
if (/^on[A-Z]/.test(k)) continue;
|
|
1501
|
+
const read3 = v;
|
|
1502
|
+
const apply = () => {
|
|
1503
|
+
const value = read3();
|
|
1504
|
+
if (value == null || value === false) a.removeAttribute?.(k);
|
|
1505
|
+
else (0, import_dom15.setAttribute)(a, k, String(value));
|
|
1506
|
+
};
|
|
1507
|
+
if (typeof a.addEventListener === "function") (0, import_signal15.createEffect)(apply);
|
|
1508
|
+
else apply();
|
|
1509
|
+
continue;
|
|
1510
|
+
}
|
|
1511
|
+
if (v != null) (0, import_dom15.setAttribute)(a, k, String(v));
|
|
1198
1512
|
}
|
|
1199
1513
|
if (typeof a.addEventListener === "function") {
|
|
1200
1514
|
a.addEventListener("click", (e) => {
|
|
1201
1515
|
if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
|
|
1516
|
+
if (!ctx) return;
|
|
1202
1517
|
e.preventDefault();
|
|
1203
1518
|
navigate();
|
|
1204
1519
|
});
|
|
@@ -1207,7 +1522,7 @@ function Link(props) {
|
|
|
1207
1522
|
if (base) (0, import_dom15.setAttribute)(a, "class", base);
|
|
1208
1523
|
}
|
|
1209
1524
|
if (typeof a.addEventListener === "function") {
|
|
1210
|
-
(0,
|
|
1525
|
+
(0, import_signal15.createEffect)(() => {
|
|
1211
1526
|
const href = read(props.href) ?? "";
|
|
1212
1527
|
a.setAttribute("href", href);
|
|
1213
1528
|
const base = read(props.className ?? props.class) ?? "";
|
|
@@ -1239,22 +1554,22 @@ var core_default = {
|
|
|
1239
1554
|
// render,
|
|
1240
1555
|
onMount,
|
|
1241
1556
|
onUnmount,
|
|
1242
|
-
createEffect:
|
|
1243
|
-
createMemo:
|
|
1244
|
-
createSignal:
|
|
1557
|
+
createEffect: import_signal18.createEffect,
|
|
1558
|
+
createMemo: import_signal18.createMemo,
|
|
1559
|
+
createSignal: import_signal18.createSignal,
|
|
1245
1560
|
createContext: createContext3,
|
|
1246
|
-
createRoot:
|
|
1247
|
-
createDeferred:
|
|
1248
|
-
createComputed:
|
|
1249
|
-
createRenderEffect:
|
|
1250
|
-
createSelector:
|
|
1251
|
-
onCleanup:
|
|
1252
|
-
getOwner:
|
|
1253
|
-
runWithOwner:
|
|
1254
|
-
batch:
|
|
1255
|
-
untrack:
|
|
1561
|
+
createRoot: import_signal18.createRoot,
|
|
1562
|
+
createDeferred: import_signal18.createDeferred,
|
|
1563
|
+
createComputed: import_signal18.createComputed,
|
|
1564
|
+
createRenderEffect: import_signal18.createRenderEffect,
|
|
1565
|
+
createSelector: import_signal19.createSelector,
|
|
1566
|
+
onCleanup: import_signal18.onCleanup,
|
|
1567
|
+
getOwner: import_signal18.getOwner,
|
|
1568
|
+
runWithOwner: import_signal18.runWithOwner,
|
|
1569
|
+
batch: import_signal18.batch,
|
|
1570
|
+
untrack: import_signal18.untrack,
|
|
1256
1571
|
useContext: useContext3,
|
|
1257
|
-
setOwner:
|
|
1572
|
+
setOwner: import_signal18.setOwner,
|
|
1258
1573
|
// Control Flow
|
|
1259
1574
|
// Show,
|
|
1260
1575
|
// For,
|