@fluixi/core 1.0.0-alpha.92 → 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.
Files changed (113) hide show
  1. package/dist/cdn/core.global.js +2 -2
  2. package/dist/src/cdn/{chunk-MDJLC3PE.mjs → chunk-7XM7Q5VR.mjs} +271 -229
  3. package/dist/src/cdn/core.cjs +360 -253
  4. package/dist/src/cdn/core.mjs +92 -20
  5. package/dist/src/cdn/{router-JYFZP3EZ.mjs → router-VOY43YNM.mjs} +7 -3
  6. package/dist/src/index.cjs +547 -232
  7. package/dist/src/index.mjs +547 -223
  8. package/dist/src/lib/client/chunk-QT3RFKH6.mjs +53 -0
  9. package/dist/src/lib/client/index.cjs +310 -176
  10. package/dist/src/lib/client/index.d.ts.map +1 -1
  11. package/dist/src/lib/client/index.js +33 -18
  12. package/dist/src/lib/client/index.mjs +86 -15
  13. package/dist/src/lib/client/{router-PHLUYVQU.mjs → router-ADTS55OP.mjs} +244 -99
  14. package/dist/src/lib/context/context.cjs +35 -72
  15. package/dist/src/lib/context/context.d.ts +45 -291
  16. package/dist/src/lib/context/context.d.ts.map +1 -1
  17. package/dist/src/lib/context/context.js +65 -397
  18. package/dist/src/lib/context/context.mjs +38 -73
  19. package/dist/src/lib/context/index.cjs +35 -72
  20. package/dist/src/lib/context/index.d.ts +2 -2
  21. package/dist/src/lib/context/index.d.ts.map +1 -1
  22. package/dist/src/lib/context/index.js +1 -5
  23. package/dist/src/lib/context/index.mjs +38 -73
  24. package/dist/src/lib/core.cjs +546 -231
  25. package/dist/src/lib/core.d.ts +3 -1
  26. package/dist/src/lib/core.d.ts.map +1 -1
  27. package/dist/src/lib/core.js +5 -3
  28. package/dist/src/lib/core.mjs +546 -222
  29. package/dist/src/lib/env/index.cjs +1 -17
  30. package/dist/src/lib/env/index.d.ts +2 -14
  31. package/dist/src/lib/env/index.d.ts.map +1 -1
  32. package/dist/src/lib/env/index.js +2 -26
  33. package/dist/src/lib/env/index.mjs +1 -17
  34. package/dist/src/lib/i18n/index.cjs +17 -2
  35. package/dist/src/lib/i18n/index.d.ts +10 -0
  36. package/dist/src/lib/i18n/index.d.ts.map +1 -1
  37. package/dist/src/lib/i18n/index.js +17 -1
  38. package/dist/src/lib/i18n/index.mjs +17 -2
  39. package/dist/src/lib/index.cjs +64 -99
  40. package/dist/src/lib/index.mjs +43 -76
  41. package/dist/src/lib/isomorphic.cjs +9 -4
  42. package/dist/src/lib/isomorphic.d.ts +9 -2
  43. package/dist/src/lib/isomorphic.d.ts.map +1 -1
  44. package/dist/src/lib/isomorphic.js +11 -4
  45. package/dist/src/lib/isomorphic.mjs +9 -4
  46. package/dist/src/lib/jsx-runtime/index.cjs +1 -1
  47. package/dist/src/lib/jsx-runtime/index.mjs +1 -1
  48. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.cjs +1 -1
  49. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.mjs +1 -1
  50. package/dist/src/lib/plugins/fluixi-routes-plugin.cjs +2 -2
  51. package/dist/src/lib/plugins/fluixi-routes-plugin.mjs +2 -2
  52. package/dist/src/lib/plugins/index.cjs +3 -3
  53. package/dist/src/lib/plugins/index.mjs +3 -3
  54. package/dist/src/lib/plugins/route-codegen.cjs +2 -2
  55. package/dist/src/lib/plugins/route-codegen.js +1 -1
  56. package/dist/src/lib/plugins/route-codegen.mjs +2 -2
  57. package/dist/src/lib/render/index.cjs +1 -1
  58. package/dist/src/lib/render/index.mjs +1 -1
  59. package/dist/src/lib/render/versions.cjs +1 -1
  60. package/dist/src/lib/render/versions.mjs +1 -1
  61. package/dist/src/lib/router/data.cjs +113 -115
  62. package/dist/src/lib/router/data.d.ts +63 -10
  63. package/dist/src/lib/router/data.d.ts.map +1 -1
  64. package/dist/src/lib/router/data.js +158 -68
  65. package/dist/src/lib/router/data.mjs +112 -112
  66. package/dist/src/lib/router/index.cjs +260 -163
  67. package/dist/src/lib/router/index.d.ts +22 -2
  68. package/dist/src/lib/router/index.d.ts.map +1 -1
  69. package/dist/src/lib/router/index.js +165 -22
  70. package/dist/src/lib/router/index.mjs +244 -143
  71. package/dist/src/lib/server/index.cjs +1 -1
  72. package/dist/src/lib/server/index.mjs +1 -1
  73. package/dist/src/lib/storage/cache.cjs +51 -0
  74. package/dist/src/lib/storage/cache.d.ts +18 -0
  75. package/dist/src/lib/storage/cache.d.ts.map +1 -0
  76. package/dist/src/lib/storage/cache.js +42 -0
  77. package/dist/src/lib/storage/cache.mjs +30 -0
  78. package/dist/src/lib/storage/index.cjs +246 -0
  79. package/dist/src/lib/storage/index.d.ts +83 -0
  80. package/dist/src/lib/storage/index.d.ts.map +1 -0
  81. package/dist/src/lib/storage/index.js +179 -0
  82. package/dist/src/lib/storage/index.mjs +231 -0
  83. package/dist/src/lib/storage/persisted.cjs +91 -0
  84. package/dist/src/lib/storage/persisted.d.ts +53 -0
  85. package/dist/src/lib/storage/persisted.d.ts.map +1 -0
  86. package/dist/src/lib/storage/persisted.js +75 -0
  87. package/dist/src/lib/storage/persisted.mjs +70 -0
  88. package/dist/src/lib/theme/color-scheme.cjs +281 -0
  89. package/dist/src/lib/theme/color-scheme.d.ts +61 -0
  90. package/dist/src/lib/theme/color-scheme.d.ts.map +1 -0
  91. package/dist/src/lib/theme/color-scheme.js +120 -0
  92. package/dist/src/lib/theme/color-scheme.mjs +265 -0
  93. package/dist/src/lib/theme/index.cjs +194 -37
  94. package/dist/src/lib/theme/index.d.ts +23 -11
  95. package/dist/src/lib/theme/index.d.ts.map +1 -1
  96. package/dist/src/lib/theme/index.js +73 -32
  97. package/dist/src/lib/theme/index.mjs +197 -35
  98. package/dist/src/lib/theme/provider.cjs +346 -0
  99. package/dist/src/lib/theme/provider.d.ts +34 -0
  100. package/dist/src/lib/theme/provider.d.ts.map +1 -0
  101. package/dist/src/lib/theme/provider.js +60 -0
  102. package/dist/src/lib/theme/provider.mjs +332 -0
  103. package/dist/src/routes.cjs +1 -1
  104. package/dist/src/routes.mjs +1 -1
  105. package/dist/src/utils.cjs +1 -1
  106. package/dist/src/utils.mjs +1 -1
  107. package/dist/src/version.generated.cjs +1 -1
  108. package/dist/src/version.generated.d.ts +1 -1
  109. package/dist/src/version.generated.js +1 -1
  110. package/dist/src/version.generated.mjs +1 -1
  111. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  112. package/package.json +18 -11
  113. package/dist/src/lib/client/chunk-VB567ABU.mjs +0 -133
@@ -21,11 +21,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  clientOnly: () => clientOnly,
24
- createMemoryStorage: () => createMemoryStorage,
25
24
  env: () => env,
26
25
  isClient: () => isClient,
27
- isServer: () => import_dom.isServer,
28
- storage: () => storage
26
+ isServer: () => import_dom.isServer
29
27
  });
30
28
  module.exports = __toCommonJS(index_exports);
31
29
  var import_dom = require("@fluixi/dom");
@@ -33,20 +31,6 @@ var import_dom2 = require("@fluixi/dom");
33
31
  function isClient() {
34
32
  return !(0, import_dom2.isServer)();
35
33
  }
36
- function createMemoryStorage() {
37
- const mem = /* @__PURE__ */ new Map();
38
- return {
39
- getItem: (k) => mem.has(k) ? mem.get(k) : null,
40
- setItem: (k, v) => void mem.set(k, String(v)),
41
- removeItem: (k) => void mem.delete(k),
42
- clear: () => mem.clear(),
43
- key: (i) => Array.from(mem.keys())[i] ?? null,
44
- get length() {
45
- return mem.size;
46
- }
47
- };
48
- }
49
- var storage = typeof localStorage !== "undefined" ? localStorage : createMemoryStorage();
50
34
  var env = {
51
35
  get window() {
52
36
  return typeof window !== "undefined" ? window : void 0;
@@ -1,23 +1,11 @@
1
1
  /**
2
2
  * Universal environment utilities, the same imports work on the server and the
3
- * client, so app code never reaches for raw globals (`localStorage`, `window`,
4
- * `document`) that don't exist under SSR and crash at module-eval time. This
5
- * replaces hand-rolled `globalThis.localStorage = ...` shims and scattered
6
- * `typeof window === 'undefined'` guards.
3
+ * client, so app code never reaches for raw globals (`window`, `document`) that don't
4
+ * exist under SSR and crash at module-eval time. Storage is `@fluixi/core/storage`.
7
5
  */
8
6
  export { isServer } from '@fluixi/dom';
9
7
  /** True in a browser (or jsdom) environment. */
10
8
  export declare function isClient(): boolean;
11
- /** A Map-backed in-memory implementation of the Web Storage API (server/tests). */
12
- export declare function createMemoryStorage(): Storage;
13
- /**
14
- * Universal key/value storage with the exact `localStorage` API. On the client it
15
- * is `localStorage`; on the server (no DOM) it is an ephemeral in-memory store, so
16
- * a module that reads `storage.getItem(...)` at import time never crashes under SSR.
17
- * Server reads/writes do not persist across requests (a later pass can back them with
18
- * the request cookie for true per-user server state).
19
- */
20
- export declare const storage: Storage;
21
9
  /**
22
10
  * Lazy, typed accessors for the browser globals. They return the real object on the
23
11
  * client and `undefined` on the server, so `env.window?.matchMedia(...)` is safe and
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/env/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,gDAAgD;AAChD,wBAAgB,QAAQ,IAAI,OAAO,CAElC;AAED,mFAAmF;AACnF,wBAAgB,mBAAmB,IAAI,OAAO,CAY7C;AAED;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,EAAE,OACsD,CAAC;AAE7E;;;;;GAKG;AACH,eAAO,MAAM,GAAG;qBACA,CAAC,MAAM,GAAG,OAAO,UAAU,CAAC,GAAG,SAAS;uBAGtC,QAAQ,GAAG,SAAS;CAGrC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;AAC1D,wBAAgB,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/env/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,gDAAgD;AAChD,wBAAgB,QAAQ,IAAI,OAAO,CAElC;AAED;;;;;GAKG;AACH,eAAO,MAAM,GAAG;qBACA,CAAC,MAAM,GAAG,OAAO,UAAU,CAAC,GAAG,SAAS;uBAGtC,QAAQ,GAAG,SAAS;CAGrC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;AAC1D,wBAAgB,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC"}
@@ -1,9 +1,7 @@
1
1
  /**
2
2
  * Universal environment utilities, the same imports work on the server and the
3
- * client, so app code never reaches for raw globals (`localStorage`, `window`,
4
- * `document`) that don't exist under SSR and crash at module-eval time. This
5
- * replaces hand-rolled `globalThis.localStorage = ...` shims and scattered
6
- * `typeof window === 'undefined'` guards.
3
+ * client, so app code never reaches for raw globals (`window`, `document`) that don't
4
+ * exist under SSR and crash at module-eval time. Storage is `@fluixi/core/storage`.
7
5
  */
8
6
  // One answer for the whole framework, from the renderer that decides it. The constant
9
7
  // this used to be was read once at module eval, so it could not see renderToString turn
@@ -14,28 +12,6 @@ import { isServer as onServer } from '@fluixi/dom';
14
12
  export function isClient() {
15
13
  return !onServer();
16
14
  }
17
- /** A Map-backed in-memory implementation of the Web Storage API (server/tests). */
18
- export function createMemoryStorage() {
19
- const mem = new Map();
20
- return {
21
- getItem: (k) => (mem.has(k) ? mem.get(k) : null),
22
- setItem: (k, v) => void mem.set(k, String(v)),
23
- removeItem: (k) => void mem.delete(k),
24
- clear: () => mem.clear(),
25
- key: (i) => Array.from(mem.keys())[i] ?? null,
26
- get length() {
27
- return mem.size;
28
- },
29
- };
30
- }
31
- /**
32
- * Universal key/value storage with the exact `localStorage` API. On the client it
33
- * is `localStorage`; on the server (no DOM) it is an ephemeral in-memory store, so
34
- * a module that reads `storage.getItem(...)` at import time never crashes under SSR.
35
- * Server reads/writes do not persist across requests (a later pass can back them with
36
- * the request cookie for true per-user server state).
37
- */
38
- export const storage = typeof localStorage !== 'undefined' ? localStorage : createMemoryStorage();
39
15
  /**
40
16
  * Lazy, typed accessors for the browser globals. They return the real object on the
41
17
  * client and `undefined` on the server, so `env.window?.matchMedia(...)` is safe and
@@ -4,20 +4,6 @@ import { isServer as onServer } from "@fluixi/dom";
4
4
  function isClient() {
5
5
  return !onServer();
6
6
  }
7
- function createMemoryStorage() {
8
- const mem = /* @__PURE__ */ new Map();
9
- return {
10
- getItem: (k) => mem.has(k) ? mem.get(k) : null,
11
- setItem: (k, v) => void mem.set(k, String(v)),
12
- removeItem: (k) => void mem.delete(k),
13
- clear: () => mem.clear(),
14
- key: (i) => Array.from(mem.keys())[i] ?? null,
15
- get length() {
16
- return mem.size;
17
- }
18
- };
19
- }
20
- var storage = typeof localStorage !== "undefined" ? localStorage : createMemoryStorage();
21
7
  var env = {
22
8
  get window() {
23
9
  return typeof window !== "undefined" ? window : void 0;
@@ -31,9 +17,7 @@ function clientOnly(fn, fallback) {
31
17
  }
32
18
  export {
33
19
  clientOnly,
34
- createMemoryStorage,
35
20
  env,
36
21
  isClient,
37
- isServer,
38
- storage
22
+ isServer
39
23
  };
@@ -1,4 +1,4 @@
1
- /*! @fluixi/core v1.0.0-alpha.92 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
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;
@@ -27,6 +27,15 @@ __export(index_exports, {
27
27
  module.exports = __toCommonJS(index_exports);
28
28
  var import_signal = require("@fluixi/reactive/signal");
29
29
  var import_dom = require("@fluixi/dom");
30
+ var RELATIVE_UNITS = [
31
+ ["year", 365 * 24 * 3600],
32
+ ["month", 30 * 24 * 3600],
33
+ ["week", 7 * 24 * 3600],
34
+ ["day", 24 * 3600],
35
+ ["hour", 3600],
36
+ ["minute", 60],
37
+ ["second", 1]
38
+ ];
30
39
  var SEED_KEY = "__i18n:locale";
31
40
  var IS_SERVER = typeof document === "undefined";
32
41
  function readSeed() {
@@ -91,7 +100,13 @@ function createI18n(config) {
91
100
  }
92
101
  const n = (value, options) => new Intl.NumberFormat(locale(), options).format(value);
93
102
  const d = (value, options) => new Intl.DateTimeFormat(locale(), options).format(value);
94
- return { t, n, d, locale, setLocale, locales: config.locales };
103
+ const rt = (value, options = {}) => {
104
+ const { now = Date.now(), ...format } = options;
105
+ const seconds = (+value - +now) / 1e3;
106
+ const [unit, size] = RELATIVE_UNITS.find(([, size2]) => Math.abs(seconds) >= size2) ?? ["second", 1];
107
+ return new Intl.RelativeTimeFormat(locale(), { numeric: "auto", ...format }).format(Math.round(seconds / size), unit);
108
+ };
109
+ return { t, n, d, rt, locale, setLocale, locales: config.locales };
95
110
  }
96
111
  function detectLocale(acceptLanguage, locales) {
97
112
  if (!acceptLanguage) return void 0;
@@ -58,6 +58,10 @@ export interface I18nConfig<L extends string, M extends Record<L, Messages> = Re
58
58
  /** Persist the chosen locale on the client. Default: a year-long `locale` cookie. */
59
59
  persist?: (locale: L) => void;
60
60
  }
61
+ export interface RelativeTimeOptions extends Intl.RelativeTimeFormatOptions {
62
+ /** The moment `value` is relative to. Defaults to the current time. */
63
+ now?: Date | number;
64
+ }
61
65
  export interface I18n<L extends string, K extends string = string> {
62
66
  /** Translate a key (autocompleted from your messages) with optional params; `count` pluralizes. */
63
67
  t: (key: K | (string & {}), params?: Record<string, unknown>) => string;
@@ -65,6 +69,12 @@ export interface I18n<L extends string, K extends string = string> {
65
69
  n: (value: number, options?: Intl.NumberFormatOptions) => string;
66
70
  /** Format a date for the active locale (`Intl.DateTimeFormat`). */
67
71
  d: (value: Date | number, options?: Intl.DateTimeFormatOptions) => string;
72
+ /**
73
+ * A date relative to now, for the active locale (`Intl.RelativeTimeFormat`): "yesterday",
74
+ * "3 days ago", "in 2 hours". The unit is the largest that fits. Pass `now` when the server
75
+ * and the client must agree, such as a time the server sent with the data.
76
+ */
77
+ rt: (value: Date | number, options?: RelativeTimeOptions) => string;
68
78
  /** The active locale: reactive on the client, per-request on the server. */
69
79
  locale: Accessor<L>;
70
80
  /** Switch the active locale (client: reactive + persisted; server: this request only). */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/i18n/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/i18n/index.ts"],"names":[],"mappings":"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"}
@@ -26,6 +26,16 @@
26
26
  */
27
27
  import { createSignal } from '@fluixi/reactive/signal';
28
28
  import { getRequestContext, getServerData } from '@fluixi/dom';
29
+ /** Largest first: the first unit the distance reaches is the one shown. */
30
+ const RELATIVE_UNITS = [
31
+ ['year', 365 * 24 * 3600],
32
+ ['month', 30 * 24 * 3600],
33
+ ['week', 7 * 24 * 3600],
34
+ ['day', 24 * 3600],
35
+ ['hour', 3600],
36
+ ['minute', 60],
37
+ ['second', 1],
38
+ ];
29
39
  const SEED_KEY = '__i18n:locale';
30
40
  const IS_SERVER = typeof document === 'undefined';
31
41
  function readSeed() {
@@ -125,7 +135,13 @@ export function createI18n(config) {
125
135
  }
126
136
  const n = (value, options) => new Intl.NumberFormat(locale(), options).format(value);
127
137
  const d = (value, options) => new Intl.DateTimeFormat(locale(), options).format(value);
128
- return { t, n, d, locale, setLocale, locales: config.locales };
138
+ const rt = (value, options = {}) => {
139
+ const { now = Date.now(), ...format } = options;
140
+ const seconds = (+value - +now) / 1000;
141
+ const [unit, size] = RELATIVE_UNITS.find(([, size]) => Math.abs(seconds) >= size) ?? ['second', 1];
142
+ return new Intl.RelativeTimeFormat(locale(), { numeric: 'auto', ...format }).format(Math.round(seconds / size), unit);
143
+ };
144
+ return { t, n, d, rt, locale, setLocale, locales: config.locales };
129
145
  }
130
146
  /** Pick the best supported locale from an `Accept-Language` header, else `undefined`. */
131
147
  export function detectLocale(acceptLanguage, locales) {
@@ -1,8 +1,17 @@
1
- /*! @fluixi/core v1.0.0-alpha.92 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/core v1.0.0-alpha.93 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
2
 
3
3
  // src/lib/i18n/index.ts
4
4
  import { createSignal } from "@fluixi/reactive/signal";
5
5
  import { getRequestContext, getServerData } from "@fluixi/dom";
6
+ var RELATIVE_UNITS = [
7
+ ["year", 365 * 24 * 3600],
8
+ ["month", 30 * 24 * 3600],
9
+ ["week", 7 * 24 * 3600],
10
+ ["day", 24 * 3600],
11
+ ["hour", 3600],
12
+ ["minute", 60],
13
+ ["second", 1]
14
+ ];
6
15
  var SEED_KEY = "__i18n:locale";
7
16
  var IS_SERVER = typeof document === "undefined";
8
17
  function readSeed() {
@@ -67,7 +76,13 @@ function createI18n(config) {
67
76
  }
68
77
  const n = (value, options) => new Intl.NumberFormat(locale(), options).format(value);
69
78
  const d = (value, options) => new Intl.DateTimeFormat(locale(), options).format(value);
70
- return { t, n, d, locale, setLocale, locales: config.locales };
79
+ const rt = (value, options = {}) => {
80
+ const { now = Date.now(), ...format } = options;
81
+ const seconds = (+value - +now) / 1e3;
82
+ const [unit, size] = RELATIVE_UNITS.find(([, size2]) => Math.abs(seconds) >= size2) ?? ["second", 1];
83
+ return new Intl.RelativeTimeFormat(locale(), { numeric: "auto", ...format }).format(Math.round(seconds / size), unit);
84
+ };
85
+ return { t, n, d, rt, locale, setLocale, locales: config.locales };
71
86
  }
72
87
  function detectLocale(acceptLanguage, locales) {
73
88
  if (!acceptLanguage) return void 0;
@@ -39,32 +39,30 @@ __export(index_exports, {
39
39
  Switch: () => import_dom12.Switch,
40
40
  VERSION: () => VERSION2,
41
41
  addClass: () => import_dom14.addClass,
42
- batch: () => import_signal10.batch,
42
+ batch: () => import_signal9.batch,
43
43
  classMap: () => import_dom13.classMap,
44
44
  cleanupDelegation: () => cleanupDelegation,
45
45
  composeProviders: () => composeProviders,
46
46
  createComponent: () => createComponent,
47
- createComputed: () => import_signal10.createComputed,
48
- createConsumer: () => createConsumer,
47
+ createComputed: () => import_signal9.createComputed,
49
48
  createContext: () => createContext3,
50
- createContextWithProvider: () => createContextWithProvider,
51
- createDebounce: () => import_signal11.createDebounce,
52
- createDeferred: () => import_signal10.createDeferred,
53
- createEffect: () => import_signal10.createEffect,
49
+ createDebounce: () => import_signal10.createDebounce,
50
+ createDeferred: () => import_signal9.createDeferred,
51
+ createEffect: () => import_signal9.createEffect,
54
52
  createIsomorphicState: () => createIsomorphicState,
55
- createMemo: () => import_signal10.createMemo,
53
+ createMemo: () => import_signal9.createMemo,
56
54
  createProvider: () => createProvider,
57
- createRenderEffect: () => import_signal10.createRenderEffect,
58
- createResource: () => import_signal10.createResource,
59
- createRoot: () => import_signal10.createRoot,
60
- createSelector: () => import_signal11.createSelector,
61
- createSignal: () => import_signal10.createSignal,
55
+ createRenderEffect: () => import_signal9.createRenderEffect,
56
+ createResource: () => import_signal9.createResource,
57
+ createRoot: () => import_signal9.createRoot,
58
+ createSelector: () => import_signal10.createSelector,
59
+ createSignal: () => import_signal9.createSignal,
62
60
  createStore: () => import_store.createStore,
63
61
  default: () => index_default,
64
62
  delegateEvents: () => import_dom14.delegateEvents,
65
63
  devOnly: () => devOnly,
66
64
  getFrameworkInfo: () => getFrameworkInfo,
67
- getOwner: () => import_signal10.getOwner,
65
+ getOwner: () => import_signal9.getOwner,
68
66
  getSharedConfig: () => getSharedConfig,
69
67
  hydrate: () => import_dom14.hydrate,
70
68
  initDelegation: () => initDelegation,
@@ -76,7 +74,7 @@ __export(index_exports, {
76
74
  jsx: () => jsx_runtime_exports.jsx,
77
75
  jsxs: () => jsx_runtime_exports.jsxs,
78
76
  lazy: () => lazy,
79
- onCleanup: () => import_signal10.onCleanup,
77
+ onCleanup: () => import_signal9.onCleanup,
80
78
  onMount: () => onMount,
81
79
  onUnmount: () => onUnmount,
82
80
  portal: () => portal,
@@ -84,27 +82,27 @@ __export(index_exports, {
84
82
  reduce: () => import_operators.reduceSignal,
85
83
  removeClass: () => import_dom14.removeClass,
86
84
  render: () => render,
87
- runWithOwner: () => import_signal10.runWithOwner,
85
+ requireContext: () => requireContext,
86
+ runWithOwner: () => import_signal9.runWithOwner,
88
87
  setAttribute: () => import_dom14.setAttribute,
89
- setOwner: () => import_signal10.setOwner,
88
+ setOwner: () => import_signal9.setOwner,
90
89
  setProperty: () => import_dom14.setProperty,
91
90
  spread: () => import_dom14.spread,
92
91
  styleMap: () => import_dom13.styleMap,
93
92
  toggleClass: () => import_dom14.toggleClass,
94
- untrack: () => import_signal10.untrack,
93
+ untrack: () => import_signal9.untrack,
95
94
  untrackStore: () => import_store.untrackStore,
96
95
  useCallback: () => useCallback,
97
96
  useContext: () => useContext3,
98
97
  useEffect: () => useEffect,
99
98
  useEventListener: () => useEventListener,
100
99
  useMemo: () => useMemo,
101
- useProvide: () => useProvide,
102
100
  useReducer: () => useReducer,
103
101
  useRef: () => useRef
104
102
  });
105
103
  module.exports = __toCommonJS(index_exports);
104
+ var import_signal9 = require("@fluixi/reactive/signal");
106
105
  var import_signal10 = require("@fluixi/reactive/signal");
107
- var import_signal11 = require("@fluixi/reactive/signal");
108
106
  var import_operators = require("@fluixi/reactive/operators");
109
107
  var import_store = require("@fluixi/reactive/store");
110
108
 
@@ -116,7 +114,7 @@ var import_signal6 = require("@fluixi/reactive/signal");
116
114
  var import_dom = require("@fluixi/dom");
117
115
 
118
116
  // src/version.generated.ts
119
- var VERSION = "1.0.0-alpha.92";
117
+ var VERSION = "1.0.0-alpha.93";
120
118
 
121
119
  // src/lib/render/versions.ts
122
120
  var import_dom2 = require("@fluixi/dom");
@@ -458,81 +456,20 @@ function cleanupDelegation() {
458
456
  // src/lib/context/context.ts
459
457
  var import_dom10 = require("@fluixi/dom");
460
458
  var import_signal7 = require("@fluixi/reactive/signal");
461
- var import_signal8 = require("@fluixi/reactive/signal");
462
- var _warnedEagerProvider = false;
463
- function warnEagerProvider() {
464
- if (_warnedEagerProvider) return;
465
- _warnedEagerProvider = true;
466
- if (typeof process !== "undefined" && true) return;
467
- console.warn(
468
- "[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>"
469
- );
470
- }
471
- function createProvider(a, value, childProps) {
472
- const isLazyForm = !!a?.Provider;
473
- const context = isLazyForm ? a : a.context;
474
- const rawValue = isLazyForm ? value : a.value;
475
- const debug = isLazyForm ? false : a.debug ?? false;
476
- if (!isLazyForm) warnEagerProvider();
477
- const resolvedValue = typeof rawValue === "function" ? rawValue() : rawValue;
478
- const sourceProps = isLazyForm ? childProps : a;
479
- return context.Provider({
480
- value: resolvedValue,
481
- get children() {
482
- return sourceProps?.children;
483
- },
484
- debug
485
- });
486
- }
487
- function createContextWithProvider(defaultValue) {
488
- const context = createContext3(defaultValue);
489
- const provider = (props) => {
490
- return createProvider(context, props.value, props);
491
- };
492
- return [context, provider];
493
- }
494
- function composeProviders(contexts, children) {
495
- if (contexts.length === 0) {
496
- return (0, import_signal8.readChildren)(() => children);
497
- }
498
- const [context, value] = contexts[0];
499
- const remaining = contexts.slice(1);
500
- return createProvider(context, value, {
501
- get children() {
502
- return composeProviders(remaining, children);
503
- }
504
- });
505
- }
506
- function createConsumer(context) {
507
- return (props) => {
508
- const value = useContext3(context);
509
- return props.children(value);
510
- };
511
- }
512
- function useProvide(context, factory) {
513
- const existing = useContext3(context);
514
- if (existing === context.defaultValue) {
515
- return factory();
516
- }
517
- return existing;
518
- }
519
459
  function createContext3(defaultValue, name) {
520
460
  const context = (0, import_signal7.createContext)(defaultValue, name);
521
- const Provider = (props) => {
522
- if (props.debug === true) {
523
- }
524
- return context.Provider({
461
+ const Provider = (props) => (
462
+ // Children stay a getter: the reactive Provider reads them after stamping the value on
463
+ // its owner. Reading `props.children` here would render them, and any <Outlet/> in them,
464
+ // before the context exists.
465
+ context.Provider({
525
466
  value: props.value,
526
467
  get children() {
527
468
  return props.children;
528
469
  },
529
470
  debug: props.debug
530
- });
531
- };
532
- if (typeof Symbol !== "undefined" && Symbol.for) {
533
- Provider.$$typeof = /* @__PURE__ */ Symbol.for("react.provider");
534
- }
535
- Provider.$$typeof = /* @__PURE__ */ Symbol.for("react.provider");
471
+ })
472
+ );
536
473
  return {
537
474
  id: context.id,
538
475
  Provider: (0, import_dom10.asProvider)(Provider),
@@ -543,10 +480,38 @@ function useContext3(context) {
543
480
  const value = (0, import_signal7.useContext)(context);
544
481
  return value !== void 0 ? value : context.defaultValue;
545
482
  }
483
+ function createProvider(context, value, props) {
484
+ const resolved = typeof value === "function" ? value() : value;
485
+ return context.Provider({
486
+ value: resolved,
487
+ get children() {
488
+ return props.children;
489
+ }
490
+ });
491
+ }
492
+ function composeProviders(providers, props) {
493
+ const outermost = providers.reduceRight(
494
+ (inner, [context, value]) => ({
495
+ get children() {
496
+ return createProvider(context, value, inner);
497
+ }
498
+ }),
499
+ props
500
+ );
501
+ return outermost.children;
502
+ }
503
+ function requireContext(context, message) {
504
+ for (let owner = (0, import_signal7.getOwner)(); owner; owner = owner.parent) {
505
+ if (owner.contexts?.has(context.id)) return useContext3(context);
506
+ }
507
+ throw new Error(message ?? `[fluixi] No Provider for ${context.id.description ?? "this context"} above this component.`);
508
+ }
546
509
 
547
510
  // src/lib/isomorphic.ts
548
- var import_signal9 = require("@fluixi/reactive/signal");
511
+ var import_signal8 = require("@fluixi/reactive/signal");
549
512
  var import_dom11 = require("@fluixi/dom");
513
+ var import_storage = require("@fluixi/storage");
514
+ var import_browser = require("@fluixi/storage/browser");
550
515
  var REGISTRY_KEY = "__fluixi_iso_states__";
551
516
  var SEED_PREFIX = "__iso:";
552
517
  function registry() {
@@ -560,7 +525,7 @@ function readSeed(key) {
560
525
  function createIsomorphicState(key, options) {
561
526
  const seed = readSeed(key);
562
527
  const initial = seed !== void 0 ? seed : typeof window !== "undefined" && options.client ? options.client() : options.fallback;
563
- const [value, set] = (0, import_signal9.createSignal)(initial);
528
+ const [value, set] = (0, import_signal8.createSignal)(initial, { name: key });
564
529
  registry().set(key, { server: options.server, set });
565
530
  return { value, set, key };
566
531
  }
@@ -579,7 +544,7 @@ var jsx_runtime_exports = {};
579
544
  __reExport(jsx_runtime_exports, require("@fluixi/jsx/jsx-runtime"));
580
545
 
581
546
  // src/lib/index.ts
582
- var import_signal12 = require("@fluixi/reactive/signal");
547
+ var import_signal11 = require("@fluixi/reactive/signal");
583
548
  var VERSION2 = "0.0.1";
584
549
  var FRAMEWORK_NAME = "Fluixi";
585
550
  function getFrameworkInfo() {
@@ -601,13 +566,13 @@ function getFrameworkInfo() {
601
566
  }
602
567
  var index_default = {
603
568
  // Core
604
- createSignal: import_signal12.createSignal,
605
- createEffect: import_signal12.createEffect,
606
- createMemo: import_signal12.createMemo,
607
- createRoot: import_signal12.createRoot,
608
- batch: import_signal12.batch,
609
- untrack: import_signal12.untrack,
610
- onCleanup: import_signal12.onCleanup,
569
+ createSignal: import_signal11.createSignal,
570
+ createEffect: import_signal11.createEffect,
571
+ createMemo: import_signal11.createMemo,
572
+ createRoot: import_signal11.createRoot,
573
+ batch: import_signal11.batch,
574
+ untrack: import_signal11.untrack,
575
+ onCleanup: import_signal11.onCleanup,
611
576
  // Context (from component for proper support)
612
577
  createContext: createContext3,
613
578
  useContext: useContext3,