@omerdlw/base-framework 1.0.6 → 2.0.0

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 (231) hide show
  1. package/dist/atoms/index.js +1 -103
  2. package/dist/atoms/index.js.map +1 -1
  3. package/dist/chunk-3BUP64Q6.js +105 -0
  4. package/dist/chunk-3BUP64Q6.js.map +1 -0
  5. package/dist/chunk-3MSK4XGK.js +9888 -0
  6. package/dist/chunk-3MSK4XGK.js.map +1 -0
  7. package/dist/chunk-4GMQKD6F.js +353 -0
  8. package/dist/chunk-4GMQKD6F.js.map +1 -0
  9. package/dist/chunk-65ZB4QTQ.js +888 -0
  10. package/dist/chunk-65ZB4QTQ.js.map +1 -0
  11. package/dist/chunk-6SG7V77J.js +577 -0
  12. package/dist/chunk-6SG7V77J.js.map +1 -0
  13. package/dist/chunk-7HQMXTNP.js +419 -0
  14. package/dist/chunk-7HQMXTNP.js.map +1 -0
  15. package/dist/chunk-7TAVYJ3A.js +371 -0
  16. package/dist/chunk-7TAVYJ3A.js.map +1 -0
  17. package/dist/chunk-AQ4BNXA2.js +349 -0
  18. package/dist/chunk-AQ4BNXA2.js.map +1 -0
  19. package/dist/chunk-CGHZSSFR.js +2166 -0
  20. package/dist/chunk-CGHZSSFR.js.map +1 -0
  21. package/dist/chunk-DGCQWQLZ.js +61 -0
  22. package/dist/chunk-DGCQWQLZ.js.map +1 -0
  23. package/dist/chunk-FIMPHODX.js +67 -0
  24. package/dist/chunk-FIMPHODX.js.map +1 -0
  25. package/dist/chunk-GF7TUX5I.js +1889 -0
  26. package/dist/chunk-GF7TUX5I.js.map +1 -0
  27. package/dist/chunk-JELG4JLT.js +454 -0
  28. package/dist/chunk-JELG4JLT.js.map +1 -0
  29. package/dist/chunk-K676GL7Z.js +51 -0
  30. package/dist/chunk-K676GL7Z.js.map +1 -0
  31. package/dist/chunk-KKQT46TP.js +26 -0
  32. package/dist/chunk-KKQT46TP.js.map +1 -0
  33. package/dist/chunk-QI3ALLIB.js +38 -0
  34. package/dist/chunk-QI3ALLIB.js.map +1 -0
  35. package/dist/chunk-QXR55VVS.js +1139 -0
  36. package/dist/chunk-QXR55VVS.js.map +1 -0
  37. package/dist/chunk-R2YGFJDJ.js +408 -0
  38. package/dist/chunk-R2YGFJDJ.js.map +1 -0
  39. package/dist/chunk-RFZQWLC5.js +27 -0
  40. package/dist/chunk-RFZQWLC5.js.map +1 -0
  41. package/dist/chunk-SYAVGTOX.js +521 -0
  42. package/dist/chunk-SYAVGTOX.js.map +1 -0
  43. package/dist/chunk-TV3WEF5G.js +784 -0
  44. package/dist/chunk-TV3WEF5G.js.map +1 -0
  45. package/dist/chunk-XASQT4CQ.js +280 -0
  46. package/dist/chunk-XASQT4CQ.js.map +1 -0
  47. package/dist/error/index.js +5 -682
  48. package/dist/error/index.js.map +1 -1
  49. package/dist/error/reporter.d.ts.map +1 -1
  50. package/dist/error/theme.d.ts +1 -1
  51. package/dist/error/theme.d.ts.map +1 -1
  52. package/dist/events.js +1 -7
  53. package/dist/events.js.map +1 -1
  54. package/dist/hooks/index.js +1 -358
  55. package/dist/hooks/index.js.map +1 -1
  56. package/dist/hooks/use-global-event.d.ts +1 -1
  57. package/dist/index.js +18 -20029
  58. package/dist/index.js.map +1 -1
  59. package/dist/kernel/index.js +2 -2035
  60. package/dist/kernel/index.js.map +1 -1
  61. package/dist/kernel/types.d.ts +1 -1
  62. package/dist/modules/ambient/analyze.d.ts +46 -0
  63. package/dist/modules/ambient/analyze.d.ts.map +1 -0
  64. package/dist/modules/ambient/constants.d.ts +1 -5
  65. package/dist/modules/ambient/constants.d.ts.map +1 -1
  66. package/dist/modules/ambient/context.d.ts.map +1 -1
  67. package/dist/modules/ambient/dom.d.ts +11 -12
  68. package/dist/modules/ambient/dom.d.ts.map +1 -1
  69. package/dist/modules/ambient/extractor.d.ts +10 -10
  70. package/dist/modules/ambient/extractor.d.ts.map +1 -1
  71. package/dist/modules/ambient/hooks.d.ts +1 -1
  72. package/dist/modules/ambient/hooks.d.ts.map +1 -1
  73. package/dist/modules/ambient/index.d.ts +6 -4
  74. package/dist/modules/ambient/index.d.ts.map +1 -1
  75. package/dist/modules/ambient/index.js +7 -762
  76. package/dist/modules/ambient/index.js.map +1 -1
  77. package/dist/modules/ambient/module.d.ts +1 -1
  78. package/dist/modules/ambient/module.d.ts.map +1 -1
  79. package/dist/modules/ambient/oklab.d.ts +36 -0
  80. package/dist/modules/ambient/oklab.d.ts.map +1 -0
  81. package/dist/modules/ambient/pipeline.d.ts +28 -0
  82. package/dist/modules/ambient/pipeline.d.ts.map +1 -0
  83. package/dist/modules/ambient/quantize.d.ts +22 -0
  84. package/dist/modules/ambient/quantize.d.ts.map +1 -0
  85. package/dist/modules/ambient/server/address.d.ts +8 -0
  86. package/dist/modules/ambient/server/address.d.ts.map +1 -0
  87. package/dist/modules/ambient/server/index.d.ts +53 -0
  88. package/dist/modules/ambient/server/index.d.ts.map +1 -0
  89. package/dist/modules/ambient/server/index.js +221 -0
  90. package/dist/modules/ambient/server/index.js.map +1 -0
  91. package/dist/modules/ambient/settings.d.ts +19 -0
  92. package/dist/modules/ambient/settings.d.ts.map +1 -0
  93. package/dist/modules/ambient/types.d.ts +105 -9
  94. package/dist/modules/ambient/types.d.ts.map +1 -1
  95. package/dist/modules/ambient/worker/index.d.ts +15 -0
  96. package/dist/modules/ambient/worker/index.d.ts.map +1 -0
  97. package/dist/modules/ambient/worker/index.js +114 -0
  98. package/dist/modules/ambient/worker/index.js.map +1 -0
  99. package/dist/modules/background/constants.d.ts +2 -2
  100. package/dist/modules/background/constants.d.ts.map +1 -1
  101. package/dist/modules/background/hooks.d.ts +1 -1
  102. package/dist/modules/background/index.js +6 -3078
  103. package/dist/modules/background/index.js.map +1 -1
  104. package/dist/modules/background/motion.d.ts +9 -7
  105. package/dist/modules/background/motion.d.ts.map +1 -1
  106. package/dist/modules/background/overlay.d.ts +3 -8
  107. package/dist/modules/background/overlay.d.ts.map +1 -1
  108. package/dist/modules/background/types.d.ts +16 -2
  109. package/dist/modules/background/types.d.ts.map +1 -1
  110. package/dist/modules/context-menu/constants.d.ts +2 -2
  111. package/dist/modules/context-menu/constants.d.ts.map +1 -1
  112. package/dist/modules/context-menu/hooks.d.ts +1 -1
  113. package/dist/modules/context-menu/index.js +10 -1896
  114. package/dist/modules/context-menu/index.js.map +1 -1
  115. package/dist/modules/context-menu/motion.d.ts +1 -8
  116. package/dist/modules/context-menu/motion.d.ts.map +1 -1
  117. package/dist/modules/context-menu/overlay.d.ts.map +1 -1
  118. package/dist/modules/context-menu/types.d.ts +16 -2
  119. package/dist/modules/context-menu/types.d.ts.map +1 -1
  120. package/dist/modules/controls/constants.d.ts +1 -1
  121. package/dist/modules/controls/constants.d.ts.map +1 -1
  122. package/dist/modules/controls/entries.d.ts +1 -1
  123. package/dist/modules/controls/hooks.d.ts +1 -1
  124. package/dist/modules/controls/index.js +4 -1110
  125. package/dist/modules/controls/index.js.map +1 -1
  126. package/dist/modules/controls/overlay.d.ts +1 -1
  127. package/dist/modules/controls/types.d.ts +2 -2
  128. package/dist/modules/dock/cards.d.ts +708 -24
  129. package/dist/modules/dock/cards.d.ts.map +1 -1
  130. package/dist/modules/dock/constants.d.ts +2 -2
  131. package/dist/modules/dock/constants.d.ts.map +1 -1
  132. package/dist/modules/dock/helpers.d.ts +2 -2
  133. package/dist/modules/dock/hooks.d.ts +2 -2
  134. package/dist/modules/dock/index.d.ts +1 -1
  135. package/dist/modules/dock/index.d.ts.map +1 -1
  136. package/dist/modules/dock/index.js +9 -12132
  137. package/dist/modules/dock/index.js.map +1 -1
  138. package/dist/modules/dock/module.d.ts +1 -1
  139. package/dist/modules/dock/motion.d.ts +41 -915
  140. package/dist/modules/dock/motion.d.ts.map +1 -1
  141. package/dist/modules/dock/overlay.d.ts.map +1 -1
  142. package/dist/modules/dock/runtime/dock.d.ts +1 -23
  143. package/dist/modules/dock/runtime/dock.d.ts.map +1 -1
  144. package/dist/modules/dock/styles.d.ts +4 -4
  145. package/dist/modules/dock/surface/hooks.d.ts +5 -20
  146. package/dist/modules/dock/surface/hooks.d.ts.map +1 -1
  147. package/dist/modules/dock/surface/machine.d.ts +4 -3
  148. package/dist/modules/dock/surface/machine.d.ts.map +1 -1
  149. package/dist/modules/dock/surface/stack.d.ts.map +1 -1
  150. package/dist/modules/dock/types.d.ts +158 -3
  151. package/dist/modules/dock/types.d.ts.map +1 -1
  152. package/dist/modules/index.js +16 -17883
  153. package/dist/modules/index.js.map +1 -1
  154. package/dist/modules/loading/constants.d.ts +1 -1
  155. package/dist/modules/loading/constants.d.ts.map +1 -1
  156. package/dist/modules/loading/context.d.ts +1 -1
  157. package/dist/modules/loading/hooks.d.ts +1 -1
  158. package/dist/modules/loading/index.js +5 -1153
  159. package/dist/modules/loading/index.js.map +1 -1
  160. package/dist/modules/loading/types.d.ts +2 -2
  161. package/dist/modules/media/context.d.ts +1 -1
  162. package/dist/modules/media/index.js +3 -570
  163. package/dist/modules/media/index.js.map +1 -1
  164. package/dist/modules/media/types.d.ts +2 -2
  165. package/dist/modules/modal/constants.d.ts +2 -2
  166. package/dist/modules/modal/constants.d.ts.map +1 -1
  167. package/dist/modules/modal/context.d.ts +1 -1
  168. package/dist/modules/modal/hooks.d.ts +3 -3
  169. package/dist/modules/modal/index.js +8 -2355
  170. package/dist/modules/modal/index.js.map +1 -1
  171. package/dist/modules/modal/motion.d.ts +3 -8
  172. package/dist/modules/modal/motion.d.ts.map +1 -1
  173. package/dist/modules/modal/overlay.d.ts.map +1 -1
  174. package/dist/modules/modal/types.d.ts +21 -0
  175. package/dist/modules/modal/types.d.ts.map +1 -1
  176. package/dist/modules/notification/constants.d.ts +2 -2
  177. package/dist/modules/notification/constants.d.ts.map +1 -1
  178. package/dist/modules/notification/context.d.ts +1 -1
  179. package/dist/modules/notification/hooks.d.ts +1 -1
  180. package/dist/modules/notification/index.js +4 -828
  181. package/dist/modules/notification/index.js.map +1 -1
  182. package/dist/modules/notification/motion.d.ts +1 -7
  183. package/dist/modules/notification/motion.d.ts.map +1 -1
  184. package/dist/modules/notification/overlay.d.ts.map +1 -1
  185. package/dist/modules/notification/types.d.ts +9 -1
  186. package/dist/modules/notification/types.d.ts.map +1 -1
  187. package/dist/overlay-TZ6L52A5.js +9 -0
  188. package/dist/overlay-TZ6L52A5.js.map +1 -0
  189. package/dist/provider.d.ts +1 -1
  190. package/dist/provider.d.ts.map +1 -1
  191. package/dist/provider.js +6 -1968
  192. package/dist/provider.js.map +1 -1
  193. package/dist/result.js +2 -63
  194. package/dist/result.js.map +1 -1
  195. package/dist/theme.d.ts +45 -8
  196. package/dist/theme.d.ts.map +1 -1
  197. package/dist/theme.js +3 -41
  198. package/dist/theme.js.map +1 -1
  199. package/dist/tokens/index.d.ts +1 -0
  200. package/dist/tokens/index.d.ts.map +1 -1
  201. package/dist/tokens/index.js +126 -155
  202. package/dist/tokens/index.js.map +1 -1
  203. package/dist/tokens/motion-config.d.ts +44 -0
  204. package/dist/tokens/motion-config.d.ts.map +1 -0
  205. package/dist/tokens/motion.d.ts +23 -174
  206. package/dist/tokens/motion.d.ts.map +1 -1
  207. package/dist/utils/index.js +4 -82
  208. package/dist/utils/index.js.map +1 -1
  209. package/dist/utils/report.d.ts.map +1 -1
  210. package/docs/README.md +1 -0
  211. package/docs/architecture-and-rules.md +4 -3
  212. package/docs/core-engine.md +7 -10
  213. package/docs/getting-started.md +4 -2
  214. package/docs/modules/ambient.md +194 -80
  215. package/docs/modules/background.md +3 -3
  216. package/docs/modules/context-menu.md +2 -2
  217. package/docs/modules/dock.md +8 -5
  218. package/docs/modules/modal.md +2 -2
  219. package/docs/modules/notification.md +2 -2
  220. package/docs/theming.md +81 -9
  221. package/package.json +22 -5
  222. package/templates/AGENTS.md +1 -1
  223. package/templates/motion/background.ts +17 -0
  224. package/templates/motion/context-menu.ts +63 -0
  225. package/templates/motion/dock.ts +327 -0
  226. package/templates/motion/modal.ts +79 -0
  227. package/templates/motion/notification.ts +27 -0
  228. package/templates/motion/tokens.ts +47 -0
  229. package/templates/tsconfig.json +7 -0
  230. package/dist/modules/ambient/color.d.ts +0 -21
  231. package/dist/modules/ambient/color.d.ts.map +0 -1
@@ -1,1156 +1,8 @@
1
1
  "use client";
2
- import { Icon as Icon$1 } from '@iconify-icon/react';
3
- import { jsx } from 'react/jsx-runtime';
4
- import { createContext, useState, useRef, useCallback, useEffect, useMemo, useContext, useSyncExternalStore, useLayoutEffect, use, useId, isValidElement, cloneElement, Children } from 'react';
5
- import { usePathname } from 'next/navigation';
6
-
7
- function Icon({
8
- className = "center",
9
- color,
10
- icon,
11
- onClick,
12
- size = 20,
13
- style,
14
- ...props
15
- }) {
16
- return /* @__PURE__ */ jsx(
17
- Icon$1,
18
- {
19
- className,
20
- height: size,
21
- icon,
22
- onClick,
23
- style: { color, ...style },
24
- width: size,
25
- ...props
26
- }
27
- );
28
- }
29
- Icon.displayName = "Icon";
30
- function Spinner({ className = "", size = 15 }) {
31
- return /* @__PURE__ */ jsx(
32
- "div",
33
- {
34
- className,
35
- "aria-label": "Loading",
36
- role: "status",
37
- children: /* @__PURE__ */ jsx(Icon, { icon: "mingcute:loading-3-fill", size })
38
- }
39
- );
40
- }
41
- Spinner.displayName = "Spinner";
42
- function useRequiredContext(context, hookName, providerName) {
43
- const value = use(context);
44
- if (value === null) {
45
- throw new Error(`${hookName} must be used within ${providerName}`);
46
- }
47
- return value;
48
- }
49
- function useStore(store, selector = (state) => state, isEqual = Object.is) {
50
- const cacheRef = useRef({
51
- isEqual: null,
52
- selected: void 0,
53
- selector: null,
54
- snapshot: null
55
- });
56
- const getSelectedSnapshot = useCallback(() => {
57
- const snapshot = store.getSnapshot();
58
- const cache = cacheRef.current;
59
- if (cache.snapshot === snapshot && cache.selector === selector && cache.isEqual === isEqual) {
60
- return cache.selected;
61
- }
62
- const selected = selector(snapshot);
63
- if (cache.snapshot !== null && cache.isEqual === isEqual && isEqual(cache.selected, selected)) {
64
- cache.snapshot = snapshot;
65
- cache.selector = selector;
66
- return cache.selected;
67
- }
68
- cacheRef.current = {
69
- isEqual,
70
- selected,
71
- selector,
72
- snapshot
73
- };
74
- return selected;
75
- }, [isEqual, selector, store]);
76
- return useSyncExternalStore(
77
- store.subscribe,
78
- getSelectedSnapshot,
79
- getSelectedSnapshot
80
- );
81
- }
82
-
83
- // src/utils/string.ts
84
- function trimToNull(value) {
85
- if (value === null || value === void 0) return null;
86
- const trimmed = String(value).trim();
87
- return trimmed.length > 0 ? trimmed : null;
88
- }
89
-
90
- // src/utils/dom.ts
91
- var isBrowser = typeof window !== "undefined";
92
-
93
- // src/utils/object.ts
94
- function isObject(value) {
95
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
96
- }
97
- function report(scope, error, level = "error") {
98
- if (process.env.NODE_ENV === "production" && typeof window !== "undefined") {
99
- return;
100
- }
101
- console[level](`[${scope}]`, error);
102
- }
103
-
104
- // src/utils/store.ts
105
- function freezeStoreSnapshot(state) {
106
- if (process.env.NODE_ENV === "production" || !state || typeof state !== "object") {
107
- return state;
108
- }
109
- const seen = /* @__PURE__ */ new WeakSet();
110
- const freeze = (value) => {
111
- if (seen.has(value) || Object.isFrozen(value)) return;
112
- seen.add(value);
113
- const prototype = Object.getPrototypeOf(value);
114
- if (Array.isArray(value) || prototype === Object.prototype || prototype === null) {
115
- for (const key of Reflect.ownKeys(value)) {
116
- const descriptor = Object.getOwnPropertyDescriptor(value, key);
117
- if (descriptor && "value" in descriptor && descriptor.value !== null) {
118
- if (typeof descriptor.value === "object") freeze(descriptor.value);
119
- }
120
- }
121
- }
122
- Object.freeze(value);
123
- };
124
- freeze(state);
125
- return state;
126
- }
127
- function createStore(initialState, { freezeSnapshots = true } = {}) {
128
- const listeners2 = /* @__PURE__ */ new Set();
129
- const prepare = freezeSnapshots ? freezeStoreSnapshot : (state) => state;
130
- let snapshot = prepare(initialState);
131
- const publish = (nextStateOrUpdater) => {
132
- const nextState = typeof nextStateOrUpdater === "function" ? nextStateOrUpdater(snapshot) : nextStateOrUpdater;
133
- if (Object.is(snapshot, nextState)) return false;
134
- snapshot = prepare(nextState);
135
- for (const listener of listeners2) {
136
- try {
137
- listener();
138
- } catch (error) {
139
- report("CoreStore subscriber", error, "warn");
140
- }
141
- }
142
- return true;
143
- };
144
- const setState = (updater) => {
145
- if (typeof updater === "function") {
146
- return publish(updater);
147
- }
148
- if (snapshot && typeof snapshot === "object" && updater && typeof updater === "object") {
149
- return publish({ ...snapshot, ...updater });
150
- }
151
- return publish(updater);
152
- };
153
- return Object.freeze({
154
- getSnapshot() {
155
- return snapshot;
156
- },
157
- publish,
158
- setState,
159
- subscribe(listener) {
160
- if (typeof listener !== "function") return () => {
161
- };
162
- listeners2.add(listener);
163
- return () => listeners2.delete(listener);
164
- }
165
- });
166
- }
167
-
168
- // src/hooks/use-isomorphic-layout-effect.ts
169
- var useIsomorphicLayoutEffect = isBrowser ? useLayoutEffect : useEffect;
170
- var listeners = /* @__PURE__ */ new Set();
171
- var activeFullscreenStateIds = /* @__PURE__ */ new Set();
172
- var ACTIVE_FULLSCREEN_ROOT_SELECTOR = '[data-fullscreen-state-root="true"][data-affect-global-state="true"]';
173
- var domObserver = null;
174
- var lastSnapshot = false;
175
- function getDomSnapshot() {
176
- if (typeof document === "undefined") {
177
- return activeFullscreenStateIds.size > 0;
178
- }
179
- return document.querySelector(ACTIVE_FULLSCREEN_ROOT_SELECTOR) !== null;
180
- }
181
- function emitChange() {
182
- listeners.forEach((listener) => listener());
183
- }
184
- function emitIfSnapshotChanged() {
185
- const nextSnapshot = getDomSnapshot();
186
- if (nextSnapshot === lastSnapshot) {
187
- return;
188
- }
189
- lastSnapshot = nextSnapshot;
190
- emitChange();
191
- }
192
- function ensureDomObserver() {
193
- if (typeof document === "undefined" || domObserver || listeners.size === 0) {
194
- return;
195
- }
196
- domObserver = new MutationObserver(() => {
197
- emitIfSnapshotChanged();
198
- });
199
- domObserver.observe(document.documentElement, {
200
- attributes: true,
201
- childList: true,
202
- subtree: true,
203
- attributeFilter: [
204
- "data-fullscreen-state",
205
- "data-fullscreen-state-root",
206
- "data-affect-global-state"
207
- ]
208
- });
209
- }
210
- function releaseDomObserver() {
211
- if (listeners.size > 0 || !domObserver) {
212
- return;
213
- }
214
- domObserver.disconnect();
215
- domObserver = null;
216
- }
217
- function subscribe(listener) {
218
- listeners.add(listener);
219
- ensureDomObserver();
220
- emitIfSnapshotChanged();
221
- return () => {
222
- listeners.delete(listener);
223
- releaseDomObserver();
224
- };
225
- }
226
- function getSnapshot() {
227
- return getDomSnapshot();
228
- }
229
- function useIsFullscreenStateActive() {
230
- return useSyncExternalStore(subscribe, getSnapshot, () => false);
231
- }
232
-
233
- // src/kernel/constants.ts
234
- var DEFAULT_SOURCE = "dynamic";
235
- var REGISTRY_SOURCES = Object.freeze({
236
- STATIC: "static",
237
- DYNAMIC: "dynamic",
238
- USER: "user"
239
- });
240
- var REGISTRY_LIFECYCLES = Object.freeze({
241
- IMMEDIATE: "immediate",
242
- GRACEFUL: "graceful",
243
- PERSISTENT: "persistent",
244
- ROUTE: "route"
245
- });
246
- var REGISTRY_VALIDATION_MODES = Object.freeze({
247
- WARN: "warn",
248
- STRICT: "strict"
249
- });
250
- var REGISTRY_METADATA_KEYS = Object.freeze([
251
- "cleanup",
252
- "cleanupDelayMs",
253
- "instanceId",
254
- "lifecycle",
255
- "priority",
256
- "source",
257
- "scope",
258
- "validation"
259
- ]);
260
- Object.freeze({
261
- [REGISTRY_SOURCES.STATIC]: 100,
262
- [REGISTRY_SOURCES.DYNAMIC]: 200,
263
- [REGISTRY_SOURCES.USER]: 300
264
- });
265
- Object.freeze({
266
- [REGISTRY_SOURCES.STATIC]: 10,
267
- [REGISTRY_SOURCES.DYNAMIC]: 20,
268
- [REGISTRY_SOURCES.USER]: 30
269
- });
270
- var REGISTRY_LIFECYCLE_VALUES = new Set(
271
- Object.values(REGISTRY_LIFECYCLES)
272
- );
273
- var REGISTRY_METADATA_KEY_SET = new Set(
274
- REGISTRY_METADATA_KEYS
275
- );
276
- var REGISTRY_SCOPE_KINDS = Object.freeze({
277
- APP: "app",
278
- SESSION: "session",
279
- ROUTE: "route",
280
- INSTANCE: "instance",
281
- WORKSPACE: "workspace"
282
- });
283
- REGISTRY_SCOPE_KINDS.APP;
284
- function getOrCreateGlobalContext(name, defaultValue) {
285
- const sym = /* @__PURE__ */ Symbol.for(`@omerdlw/base-framework/context/${name}`);
286
- const store = globalThis;
287
- if (!store[sym]) {
288
- store[sym] = createContext(defaultValue);
289
- }
290
- return store[sym];
291
- }
292
-
293
- // src/kernel/utils.ts
294
- function parseFiniteNumber(value) {
295
- const parsed = Number(value);
296
- return Number.isFinite(parsed) ? parsed : null;
297
- }
298
- function getValidString(value, fallback = null) {
299
- return trimToNull(value) ?? fallback;
300
- }
301
-
302
- // src/kernel/schema.ts
303
- function resolveLifecycle(metadata, fallback) {
304
- const lifecycle = metadata?.lifecycle ?? metadata?.cleanup;
305
- return lifecycle && REGISTRY_LIFECYCLE_VALUES.has(lifecycle) ? lifecycle : fallback;
306
- }
307
- function validateRegistryMetadata(metadata) {
308
- if (metadata === void 0 || metadata === null)
309
- return { issues: [], valid: true };
310
- if (!isObject(metadata))
311
- return { issues: ["registry metadata must be an object"], valid: false };
312
- const issues = [];
313
- Object.keys(metadata).forEach((key) => {
314
- if (!REGISTRY_METADATA_KEY_SET.has(key))
315
- issues.push(`unknown registry metadata field: ${key}`);
316
- });
317
- if (metadata.source !== void 0 && !getValidString(metadata.source))
318
- issues.push("source must be a non-empty string");
319
- if (metadata.instanceId !== void 0 && !getValidString(metadata.instanceId))
320
- issues.push("instanceId must be a non-empty string");
321
- if (metadata.scope !== void 0 && !getValidString(metadata.scope))
322
- issues.push("scope must be a non-empty string");
323
- if (metadata.priority !== void 0 && parseFiniteNumber(metadata.priority) === null)
324
- issues.push("priority must be a finite number");
325
- if (metadata.cleanupDelayMs !== void 0) {
326
- const delay = parseFiniteNumber(metadata.cleanupDelayMs);
327
- if (delay === null || delay < 0)
328
- issues.push("cleanupDelayMs must be a non-negative finite number");
329
- }
330
- const lifecycle = metadata.lifecycle ?? metadata.cleanup;
331
- if (lifecycle !== void 0 && !REGISTRY_LIFECYCLE_VALUES.has(String(lifecycle))) {
332
- issues.push(
333
- `lifecycle must be one of: ${[...REGISTRY_LIFECYCLE_VALUES].join(", ")}`
334
- );
335
- }
336
- if (metadata.validation !== void 0 && !Object.values(REGISTRY_VALIDATION_MODES).includes(
337
- metadata.validation
338
- )) {
339
- issues.push(
340
- `validation must be one of: ${Object.values(REGISTRY_VALIDATION_MODES).join(", ")}`
341
- );
342
- }
343
- return { issues, valid: issues.length === 0 };
344
- }
345
- function normalizeRegistryMetadata(metadata, {
346
- defaultCleanupDelayMs = null,
347
- defaultLifecycle = null,
348
- defaultSource = DEFAULT_SOURCE
349
- } = {}) {
350
- const registryMeta = isObject(metadata) ? metadata : {};
351
- const normalizedDefaultDelay = parseFiniteNumber(defaultCleanupDelayMs);
352
- const fallbackCleanupDelayMs = normalizedDefaultDelay !== null && normalizedDefaultDelay >= 0 ? normalizedDefaultDelay : null;
353
- const fallbackLifecycle = defaultLifecycle && REGISTRY_LIFECYCLE_VALUES.has(defaultLifecycle) ? defaultLifecycle : null;
354
- const source = getValidString(registryMeta.source) || getValidString(defaultSource, DEFAULT_SOURCE) || DEFAULT_SOURCE;
355
- const scope = getValidString(registryMeta.scope);
356
- const priority = parseFiniteNumber(registryMeta.priority);
357
- const lifecycle = resolveLifecycle(registryMeta, fallbackLifecycle);
358
- const validation = isValidationMode(registryMeta.validation) ? registryMeta.validation : null;
359
- const cleanupDelayCandidate = parseFiniteNumber(registryMeta.cleanupDelayMs);
360
- let cleanupDelayMs = cleanupDelayCandidate !== null && cleanupDelayCandidate >= 0 ? cleanupDelayCandidate : fallbackCleanupDelayMs;
361
- if (lifecycle === REGISTRY_LIFECYCLES.IMMEDIATE) {
362
- cleanupDelayMs = 0;
363
- } else if ((lifecycle === REGISTRY_LIFECYCLES.GRACEFUL || lifecycle === REGISTRY_LIFECYCLES.ROUTE) && cleanupDelayMs === null) {
364
- cleanupDelayMs = fallbackCleanupDelayMs;
365
- }
366
- return {
367
- cleanupDelayMs,
368
- lifecycle,
369
- priority,
370
- registerOptions: {
371
- ...priority !== null && { priority },
372
- ...validation === REGISTRY_VALIDATION_MODES.STRICT && { validation },
373
- ...scope && { scope }
374
- },
375
- source,
376
- ...scope && { scope },
377
- ...validation && { validation }
378
- };
379
- }
380
- function isValidationMode(value) {
381
- return Object.values(REGISTRY_VALIDATION_MODES).includes(value);
382
- }
383
- function pickRegistryMetadata(options) {
384
- if (!isObject(options)) return {};
385
- return Object.fromEntries(
386
- REGISTRY_METADATA_KEYS.filter((key) => options[key] !== void 0).map(
387
- (key) => [key, options[key]]
388
- )
389
- );
390
- }
391
- var RegistryContext = getOrCreateGlobalContext(
392
- "RegistryContext",
393
- null
394
- );
395
- function useRegistryActions() {
396
- return useRequiredContext(
397
- RegistryContext,
398
- "useRegistryActions",
399
- "RegistryProvider"
400
- ).actions;
401
- }
402
- function useRegistrySubscription() {
403
- return useRequiredContext(
404
- RegistryContext,
405
- "useRegistrySubscription",
406
- "RegistryProvider"
407
- ).subscription;
408
- }
409
- function useRegistryValue(type, key) {
410
- const { getSnapshot: getSnapshot2, subscribe: subscribe2 } = useRegistrySubscription();
411
- const subscribeToKey = useCallback(
412
- (listener) => subscribe2(type, key, listener),
413
- [key, subscribe2, type]
414
- );
415
- const getValue = useCallback(
416
- () => getSnapshot2(type, key),
417
- [getSnapshot2, key, type]
418
- );
419
- return useSyncExternalStore(subscribeToKey, getValue, getValue);
420
- }
421
- var EMPTY_MODULES = Object.freeze([]);
422
- var ModuleHostContext = getOrCreateGlobalContext("ModuleHostContext", null);
423
- function selectModuleSlice(coreModule, config) {
424
- const slice = coreModule.page?.select ? coreModule.page.select(config) : config[coreModule.id];
425
- return slice ?? null;
426
- }
427
- function createModulePayload(modules, config, metadata = {}) {
428
- const payload = {};
429
- let hasSlices = false;
430
- for (const coreModule of modules) {
431
- if (!coreModule.page?.entries) continue;
432
- const slice = selectModuleSlice(coreModule, config);
433
- if (slice === null) continue;
434
- payload[coreModule.id] = slice;
435
- hasSlices = true;
436
- }
437
- if (!hasSlices) return null;
438
- return {
439
- ...payload,
440
- registry: {
441
- ...metadata,
442
- ...isObject(config.registry) ? config.registry : {}
443
- }
444
- };
445
- }
446
- function useInstalledModules() {
447
- return use(ModuleHostContext)?.modules ?? EMPTY_MODULES;
448
- }
449
-
450
- // src/kernel/handlers.ts
451
- function isPersistentLifecycle(lifecycle) {
452
- return lifecycle === REGISTRY_LIFECYCLES.PERSISTENT;
453
- }
454
- function runRegistrationBatch(context, executor) {
455
- return typeof context.batch === "function" ? context.batch(executor) : executor(context);
456
- }
457
- function createEntryCleanupKey(type, key, source, instanceId, scope) {
458
- return JSON.stringify([
459
- "entry",
460
- type,
461
- key,
462
- scope ?? null,
463
- source,
464
- instanceId
465
- ]);
466
- }
467
- function getCleanupScope(context) {
468
- return context?.cleanupScope || /* @__PURE__ */ new Map();
469
- }
470
- function clearCleanupTimer(scope, cleanupKey) {
471
- const lifecycle = scope.get(cleanupKey);
472
- if (!lifecycle) return;
473
- lifecycle.cancelled = true;
474
- if (lifecycle.timerId !== null) clearTimeout(lifecycle.timerId);
475
- scope.delete(cleanupKey);
476
- }
477
- function scheduleCleanup(scope, cleanupKey, callback, delayMs) {
478
- clearCleanupTimer(scope, cleanupKey);
479
- const lifecycle = {
480
- cancelled: false,
481
- timerId: null
482
- };
483
- lifecycle.timerId = setTimeout(() => {
484
- if (lifecycle.cancelled || scope.get(cleanupKey) !== lifecycle) return;
485
- scope.delete(cleanupKey);
486
- callback();
487
- }, delayMs);
488
- scope.set(cleanupKey, lifecycle);
489
- }
490
- function collectModuleRegistrations(coreModule, slice, pageMetadata, context) {
491
- const definition = coreModule.registry;
492
- const toEntries = coreModule.page?.entries;
493
- if (!definition || !toEntries || slice == null || slice === false) return [];
494
- const type = coreModule.id;
495
- const items = Array.isArray(slice) ? slice : [slice];
496
- const registrations = [];
497
- for (const item of items) {
498
- if (item == null || item === false) continue;
499
- const itemMetadata = isObject(item) && isObject(item.registry) ? item.registry : {};
500
- const metadata = { ...pageMetadata, ...itemMetadata };
501
- if (metadata.validation === "strict" && !validateRegistryMetadata(metadata).valid) {
502
- continue;
503
- }
504
- const payload = isObject(item) ? Object.fromEntries(
505
- Object.entries(item).filter(([key]) => key !== "registry")
506
- ) : item;
507
- const { cleanupDelayMs, lifecycle, registerOptions, scope, source } = normalizeRegistryMetadata(metadata, {
508
- defaultCleanupDelayMs: definition.cleanupDelayMs ?? null,
509
- defaultLifecycle: definition.lifecycle,
510
- defaultSource: DEFAULT_SOURCE
511
- });
512
- for (const { key, value } of toEntries(payload, context) ?? []) {
513
- const validation = definition.validate?.(value);
514
- if (validation && !validation.valid) {
515
- report(`Registry ${type} config is invalid`, validation.issues, "warn");
516
- continue;
517
- }
518
- registrations.push({
519
- cleanupDelayMs,
520
- cleanupKey: createEntryCleanupKey(
521
- type,
522
- key,
523
- source,
524
- context.instanceId,
525
- scope
526
- ),
527
- key,
528
- lifecycle,
529
- registerOptions,
530
- scope,
531
- source,
532
- type,
533
- value
534
- });
535
- }
536
- }
537
- return registrations;
538
- }
539
- var NO_CLEANUP = () => {
540
- };
541
- function applyRegistryConfig(config, context) {
542
- const modules = context.modules ?? [];
543
- if (!config || modules.length === 0) return NO_CLEANUP;
544
- const pageMetadata = isObject(config.registry) ? config.registry : {};
545
- const slices = config;
546
- const registrations = modules.flatMap((coreModule) => {
547
- try {
548
- return collectModuleRegistrations(
549
- coreModule,
550
- slices[coreModule.id],
551
- pageMetadata,
552
- context
553
- );
554
- } catch (error) {
555
- report(`Registry apply (${coreModule.id})`, error);
556
- return [];
557
- }
558
- });
559
- if (registrations.length === 0) return NO_CLEANUP;
560
- const cleanupScope = getCleanupScope(context);
561
- const owner = (registration) => ({
562
- instanceId: context.instanceId,
563
- scope: registration.scope,
564
- source: registration.source
565
- });
566
- runRegistrationBatch(context, (queue) => {
567
- registrations.forEach(
568
- ({ cleanupKey, key, registerOptions, source, type, value }) => {
569
- clearCleanupTimer(cleanupScope, cleanupKey);
570
- queue.register(type, key, value, source, registerOptions);
571
- }
572
- );
573
- });
574
- return () => {
575
- const immediate = [];
576
- registrations.forEach((registration) => {
577
- if (isPersistentLifecycle(registration.lifecycle)) return;
578
- const { cleanupDelayMs, cleanupKey, key, type } = registration;
579
- if (typeof cleanupDelayMs === "number" && cleanupDelayMs > 0) {
580
- scheduleCleanup(
581
- cleanupScope,
582
- cleanupKey,
583
- () => context.unregister(type, key, owner(registration)),
584
- cleanupDelayMs
585
- );
586
- } else {
587
- immediate.push(registration);
588
- }
589
- });
590
- if (immediate.length === 0) return;
591
- runRegistrationBatch(context, (queue) => {
592
- immediate.forEach(
593
- (registration) => queue.unregister(
594
- registration.type,
595
- registration.key,
596
- owner(registration)
597
- )
598
- );
599
- });
600
- };
601
- }
602
-
603
- // src/kernel/hooks.ts
604
- function withInstanceId(instanceId, sourceOrOptions, optionsArg) {
605
- if (typeof sourceOrOptions === "string") {
606
- return {
607
- optionsArg: { ...isObject(optionsArg) ? optionsArg : {}, instanceId },
608
- sourceOrOptions
609
- };
610
- }
611
- if (isObject(sourceOrOptions)) {
612
- return {
613
- optionsArg,
614
- sourceOrOptions: { ...sourceOrOptions, instanceId }
615
- };
616
- }
617
- return {
618
- optionsArg: void 0,
619
- sourceOrOptions: {
620
- ...isObject(optionsArg) ? optionsArg : {},
621
- instanceId
622
- }
623
- };
624
- }
625
- function withInstanceIdForUnregister(instanceId, sourceOrOptions) {
626
- if (typeof sourceOrOptions === "string") {
627
- return { instanceId, source: sourceOrOptions };
628
- }
629
- if (isObject(sourceOrOptions)) {
630
- return { ...sourceOrOptions, instanceId };
631
- }
632
- return { instanceId };
633
- }
634
- function resolveRegisterArgsWithInstance(instanceId, sourceOrOptions, optionsArg) {
635
- const input = withInstanceId(instanceId, sourceOrOptions, optionsArg);
636
- return [input.sourceOrOptions, input.optionsArg];
637
- }
638
- var MAX_STABILIZATION_DEPTH = 64;
639
- function createStableFunctionEntry(fn) {
640
- const entry = {
641
- current: fn,
642
- stable(...args) {
643
- return entry.current?.apply(this, args);
644
- }
645
- };
646
- return entry;
647
- }
648
- function isDirectRegistryComponentPath(path, componentSlices) {
649
- const match = /^config\.([^.[]+)\.[^.[]+$/.exec(path);
650
- return Boolean(match && componentSlices.has(match[1]));
651
- }
652
- function isReactNodeLike(value) {
653
- return value === null || value === void 0 || typeof value === "boolean" || typeof value === "string" || typeof value === "number" || isValidElement(value);
654
- }
655
- function isStabilizableObject(value) {
656
- return typeof value === "object" && value !== null && !Array.isArray(value) && !isValidElement(value);
657
- }
658
- function hasSameObjectKeys(previousValue, nextValue) {
659
- if (!isStabilizableObject(previousValue) || !isStabilizableObject(nextValue)) {
660
- return false;
661
- }
662
- const previousKeys = Object.keys(previousValue);
663
- const nextKeys = Object.keys(nextValue);
664
- if (previousKeys.length !== nextKeys.length) return false;
665
- return nextKeys.every(
666
- (key) => Object.prototype.hasOwnProperty.call(previousValue, key)
667
- );
668
- }
669
- function stabilizeRegistryValue(value, path, scope, previousValue, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
670
- if (depth > MAX_STABILIZATION_DEPTH) return value;
671
- if (typeof value === "function") {
672
- const isComponent = value.name && /^[A-Z]/.test(value.name);
673
- if (isComponent || isDirectRegistryComponentPath(path, scope.componentSlices)) {
674
- return value;
675
- }
676
- scope.usedPaths.add(path);
677
- let entry = scope.functionEntries.get(path);
678
- if (!entry) {
679
- entry = createStableFunctionEntry(value);
680
- scope.functionEntries.set(path, entry);
681
- } else {
682
- entry.current = value;
683
- }
684
- return entry.stable;
685
- }
686
- if (value && typeof value === "object") {
687
- if (seen.has(value)) return value;
688
- seen.add(value);
689
- }
690
- if (isValidElement(value)) {
691
- const nextProps = stabilizeRegistryValue(
692
- value.props,
693
- `${path}.props`,
694
- scope,
695
- isValidElement(previousValue) ? previousValue.props : void 0,
696
- seen,
697
- depth + 1
698
- );
699
- if (isValidElement(previousValue) && previousValue.type === value.type && previousValue.key === value.key && previousValue.props === nextProps) {
700
- return previousValue;
701
- }
702
- return cloneElement(value, nextProps);
703
- }
704
- if (Array.isArray(value)) {
705
- const nextValue = value.every(isReactNodeLike) ? Children.toArray(value) : value;
706
- const previousArray = Array.isArray(previousValue) ? previousValue : null;
707
- let hasChanged2 = !previousArray || previousArray.length !== nextValue.length;
708
- const stabilizedValue2 = nextValue.map((item, index) => {
709
- const nextItem = stabilizeRegistryValue(
710
- item,
711
- `${path}[${index}]`,
712
- scope,
713
- previousArray?.[index],
714
- seen,
715
- depth + 1
716
- );
717
- if (!previousArray || nextItem !== previousArray[index]) {
718
- hasChanged2 = true;
719
- }
720
- return nextItem;
721
- });
722
- return !hasChanged2 ? previousArray : stabilizedValue2;
723
- }
724
- if (typeof value !== "object" || value === null) {
725
- return value;
726
- }
727
- const source = value;
728
- const previousRecord = previousValue;
729
- const stabilizedValue = {};
730
- const canReusePrevious = hasSameObjectKeys(previousValue, value);
731
- let hasChanged = !canReusePrevious;
732
- Object.keys(source).forEach((key) => {
733
- const nextValue = stabilizeRegistryValue(
734
- source[key],
735
- `${path}.${key}`,
736
- scope,
737
- previousRecord?.[key],
738
- seen,
739
- depth + 1
740
- );
741
- stabilizedValue[key] = nextValue;
742
- if (!canReusePrevious || nextValue !== previousRecord?.[key]) {
743
- hasChanged = true;
744
- }
745
- });
746
- return !hasChanged ? previousValue : stabilizedValue;
747
- }
748
- function useAppliedRegistryConfig(payload, context, componentSlices) {
749
- const functionEntriesRef = useRef(/* @__PURE__ */ new Map());
750
- const appliedRef = useRef(null);
751
- useIsomorphicLayoutEffect(() => {
752
- const previous = appliedRef.current;
753
- if (previous && previous.payload === payload && previous.context === context) {
754
- return;
755
- }
756
- const functionEntries = functionEntriesRef.current;
757
- const usedPaths = /* @__PURE__ */ new Set();
758
- const config = stabilizeRegistryValue(
759
- payload,
760
- "config",
761
- { componentSlices, functionEntries, usedPaths },
762
- previous?.config
763
- );
764
- functionEntries.forEach((_entry, path) => {
765
- if (!usedPaths.has(path)) functionEntries.delete(path);
766
- });
767
- if (previous && previous.config === config && previous.context === context) {
768
- previous.payload = payload;
769
- return;
770
- }
771
- previous?.cleanup();
772
- appliedRef.current = {
773
- cleanup: applyRegistryConfig(config, context),
774
- config,
775
- context,
776
- payload
777
- };
778
- });
779
- useIsomorphicLayoutEffect(
780
- () => () => {
781
- appliedRef.current?.cleanup();
782
- appliedRef.current = null;
783
- },
784
- []
785
- );
786
- }
787
- function createRegistryApplyContext(actions, {
788
- cleanupScope = /* @__PURE__ */ new Map(),
789
- instanceId,
790
- modules = [],
791
- pathname
792
- }) {
793
- const stamp = (queue) => ({
794
- register: (type, key, item, sourceOrOptions, optionsArg) => queue.register(
795
- type,
796
- key,
797
- item,
798
- ...resolveRegisterArgsWithInstance(
799
- instanceId,
800
- sourceOrOptions,
801
- optionsArg
802
- )
803
- ),
804
- unregister: (type, key, sourceOrOptions) => queue.unregister(
805
- type,
806
- key,
807
- withInstanceIdForUnregister(instanceId, sourceOrOptions)
808
- )
809
- });
810
- return {
811
- ...stamp(actions),
812
- batch: (executor) => typeof executor === "function" ? actions.batch((queue) => executor(stamp(queue))) : 0,
813
- cleanupScope,
814
- instanceId,
815
- modules,
816
- pathname
817
- };
818
- }
819
- function useRegistry(config, metadata) {
820
- const { batch, register, unregister } = useRegistryActions();
821
- const pathname = usePathname();
822
- const modules = useInstalledModules();
823
- const instanceId = `registry-instance-${useId()}`;
824
- const [cleanupScope] = useState(
825
- () => /* @__PURE__ */ new Map()
826
- );
827
- const context = useMemo(
828
- () => createRegistryApplyContext(
829
- { batch, register, unregister },
830
- {
831
- cleanupScope,
832
- instanceId,
833
- modules,
834
- pathname
835
- }
836
- ),
837
- [batch, cleanupScope, instanceId, modules, pathname, register, unregister]
838
- );
839
- const payload = useMemo(
840
- () => config ? createModulePayload(modules, config, metadata) : null,
841
- [config, metadata, modules]
842
- );
843
- const componentSlices = useMemo(
844
- () => new Set(
845
- modules.filter(
846
- (coreModule) => coreModule.registry?.valueKind === "component"
847
- ).map((coreModule) => coreModule.id)
848
- ),
849
- [modules]
850
- );
851
- useAppliedRegistryConfig(payload, context, componentSlices);
852
- }
853
- function defineModule(coreModule) {
854
- return Object.freeze({ ...coreModule });
855
- }
856
- createStore(void 0);
857
-
858
- // src/kernel/adapters.ts
859
- function useModuleRegistration(id, value, options) {
860
- const coreModule = useInstalledModules().find(
861
- (candidate) => candidate.id === id
862
- );
863
- const config = coreModule && options?.enabled !== false && value != null ? { [id]: value } : null;
864
- useRegistry(config, pickRegistryMetadata(options));
865
- }
866
- function defineThemeSpec(id) {
867
- return Object.freeze({ id });
868
- }
869
- var EMPTY = /* @__PURE__ */ new Map();
870
- var ThemeContext = getOrCreateGlobalContext("ThemeContext", EMPTY);
871
- function useTheme(spec) {
872
- const config = useContext(ThemeContext).get(spec.id);
873
- if (!config) {
874
- throw new Error(
875
- `Theme "${spec.id}" is missing. Ensure its theme configuration is provided to <ThemeProvider themes={[...]}> (e.g. in src/config/ or your theme setup).`
876
- );
877
- }
878
- return {
879
- slots: config.slots,
880
- styles: config.styles ?? {}
881
- };
882
- }
883
-
884
- // src/modules/loading/constants.ts
885
- var DEFAULT_LOADING_STATE = Object.freeze({
886
- isLoading: false,
887
- skeleton: null,
888
- minDuration: 0,
889
- showOverlay: true,
890
- message: null
891
- });
892
- var DEFAULT_LOADING_STATE_WITH_PAGE = Object.freeze({
893
- ...DEFAULT_LOADING_STATE,
894
- isPageLoading: false
895
- });
896
- var INERT_LOADING_ACTIONS = Object.freeze({
897
- setLoading: () => {
898
- },
899
- setSkeleton: () => {
900
- },
901
- startLoading: () => {
902
- },
903
- stopLoading: () => {
904
- },
905
- withLoading: async (task) => typeof task === "function" ? task() : task
906
- });
907
- var LOADING_REGISTRY_KEY = "page-loading";
908
- var loadingTheme = defineThemeSpec("loading");
909
-
910
- // src/modules/loading/state.ts
911
- function normalizeLoadingOptions(options = {}) {
912
- const minDuration = Number(options.minDuration);
913
- return {
914
- message: typeof options.message === "string" ? options.message : null,
915
- minDuration: Number.isFinite(minDuration) && minDuration > 0 ? minDuration : 0,
916
- showOverlay: options.showOverlay !== false,
917
- skeleton: options.skeleton ?? null
918
- };
919
- }
920
- function selectPageLoading(loading) {
921
- if (loading === void 0 || loading === null) return null;
922
- if (typeof loading === "boolean") return { isLoading: loading };
923
- if (typeof loading === "string") return { isLoading: true, message: loading };
924
- return loading;
925
- }
926
- function resolveLoadingState(manualState, registryLoading) {
927
- if (registryLoading?.isLoading) {
928
- const normalized = normalizeLoadingOptions(registryLoading);
929
- return {
930
- ...normalized,
931
- isLoading: true,
932
- isPageLoading: true
933
- };
934
- }
935
- return {
936
- ...manualState,
937
- isPageLoading: manualState.isLoading
938
- };
939
- }
940
- function calculateRemainingMinDuration(startTime, minDuration, now = Date.now()) {
941
- if (startTime === null || minDuration <= 0) return 0;
942
- const elapsed = now - startTime;
943
- const remaining = minDuration - elapsed;
944
- return remaining > 0 ? remaining : 0;
945
- }
946
- var LoadingContext = getOrCreateGlobalContext("LoadingContext", null);
947
- var NOOP_LOADING_STORE = createStore(
948
- DEFAULT_LOADING_STATE_WITH_PAGE
949
- );
950
- function LoadingProvider({ children }) {
951
- const [manualState, setManualState] = useState(
952
- DEFAULT_LOADING_STATE
953
- );
954
- const startTimeRef = useRef(null);
955
- const minDurationRef = useRef(0);
956
- const stopTimerRef = useRef(null);
957
- const registryLoading = useRegistryValue(
958
- "loading",
959
- LOADING_REGISTRY_KEY
960
- );
961
- const clearStopTimer = useCallback(() => {
962
- if (stopTimerRef.current !== null) {
963
- clearTimeout(stopTimerRef.current);
964
- stopTimerRef.current = null;
965
- }
966
- }, []);
967
- const resetState = useCallback(() => {
968
- clearStopTimer();
969
- minDurationRef.current = 0;
970
- startTimeRef.current = null;
971
- setManualState(DEFAULT_LOADING_STATE);
972
- }, [clearStopTimer]);
973
- const startLoading = useCallback(
974
- (options = {}) => {
975
- clearStopTimer();
976
- const nextState = normalizeLoadingOptions(options);
977
- startTimeRef.current = Date.now();
978
- minDurationRef.current = nextState.minDuration;
979
- setManualState({
980
- ...nextState,
981
- isLoading: true
982
- });
983
- },
984
- [clearStopTimer]
985
- );
986
- const stopLoading = useCallback(() => {
987
- const remaining = calculateRemainingMinDuration(
988
- startTimeRef.current,
989
- minDurationRef.current
990
- );
991
- if (remaining <= 0) {
992
- resetState();
993
- return;
994
- }
995
- clearStopTimer();
996
- stopTimerRef.current = setTimeout(resetState, remaining);
997
- }, [clearStopTimer, resetState]);
998
- const setLoading = useCallback(
999
- (value2) => {
1000
- if (value2) startLoading();
1001
- else stopLoading();
1002
- },
1003
- [startLoading, stopLoading]
1004
- );
1005
- const setSkeleton = useCallback((nextSkeleton) => {
1006
- setManualState((currentState) => {
1007
- const skeleton = typeof nextSkeleton === "function" ? nextSkeleton(currentState.skeleton) : nextSkeleton;
1008
- return currentState.skeleton === skeleton ? currentState : { ...currentState, skeleton };
1009
- });
1010
- }, []);
1011
- const withLoading = useCallback(
1012
- async (task, options = {}) => {
1013
- startLoading(
1014
- typeof options === "string" ? { message: options } : options
1015
- );
1016
- try {
1017
- return typeof task === "function" ? await task() : await task;
1018
- } finally {
1019
- stopLoading();
1020
- }
1021
- },
1022
- [startLoading, stopLoading]
1023
- );
1024
- useEffect(() => clearStopTimer, [clearStopTimer]);
1025
- const state = useMemo(
1026
- () => resolveLoadingState(manualState, registryLoading),
1027
- [manualState, registryLoading]
1028
- );
1029
- const actions = useMemo(
1030
- () => ({
1031
- setLoading,
1032
- setSkeleton,
1033
- startLoading,
1034
- stopLoading,
1035
- withLoading
1036
- }),
1037
- [setLoading, setSkeleton, startLoading, stopLoading, withLoading]
1038
- );
1039
- const [store] = useState(
1040
- () => createStore(state, { freezeSnapshots: false })
1041
- );
1042
- useIsomorphicLayoutEffect(() => {
1043
- store.publish(state);
1044
- }, [state, store]);
1045
- const value = useMemo(
1046
- () => ({ actions, store }),
1047
- [actions, store]
1048
- );
1049
- return /* @__PURE__ */ jsx(LoadingContext, { value, children });
1050
- }
1051
-
1052
- // src/modules/loading/hooks.ts
1053
- function useLoadingRegistration(config, options) {
1054
- useModuleRegistration("loading", config, options);
1055
- }
1056
- function useLoadingState() {
1057
- const { store } = useRequiredContext(
1058
- LoadingContext,
1059
- "useLoadingState",
1060
- "LoadingProvider"
1061
- );
1062
- return useStore(store);
1063
- }
1064
- function useLoadingActions() {
1065
- return useRequiredContext(
1066
- LoadingContext,
1067
- "useLoadingActions",
1068
- "LoadingProvider"
1069
- ).actions;
1070
- }
1071
- function useLoading(config, options) {
1072
- useLoadingRegistration(config, options);
1073
- const actions = useLoadingActions();
1074
- const state = useLoadingState();
1075
- return useMemo(() => ({ ...state, ...actions }), [actions, state]);
1076
- }
1077
- function useOptionalLoadingState(selector, isEqual) {
1078
- const ctx = useContext(LoadingContext);
1079
- return useStore(
1080
- ctx?.store ?? NOOP_LOADING_STORE,
1081
- selector,
1082
- isEqual
1083
- );
1084
- }
1085
- function useOptionalLoadingActions() {
1086
- const ctx = useContext(LoadingContext);
1087
- return ctx?.actions ?? INERT_LOADING_ACTIONS;
1088
- }
1089
- function useLoadingOverlayModel() {
1090
- const { isLoading, skeleton, showOverlay } = useLoadingState();
1091
- const isFullscreenStateActive = useIsFullscreenStateActive();
1092
- const isVisible = isLoading && showOverlay && !isFullscreenStateActive;
1093
- const theme = useTheme(loadingTheme);
1094
- return { skeleton, isVisible, theme };
1095
- }
1096
- function LoadingOverlay() {
1097
- const { skeleton, isVisible, theme } = useLoadingOverlayModel();
1098
- if (!isVisible) return null;
1099
- return /* @__PURE__ */ jsx(
1100
- "div",
1101
- {
1102
- className: theme.slots.overlay,
1103
- "aria-label": "Loading",
1104
- "aria-busy": "true",
1105
- role: "status",
1106
- style: theme.styles.overlay,
1107
- children: skeleton || /* @__PURE__ */ jsx(Spinner, { size: 30 })
1108
- }
1109
- );
1110
- }
1111
- function useLoadingPage(_slice, page) {
1112
- const actions = useLoadingActions();
1113
- return useMemo(
1114
- () => ({
1115
- ...actions,
1116
- set: (loading) => page.set({ loading })
1117
- }),
1118
- [actions, page]
1119
- );
1120
- }
1121
- function defineLoading(definition = {}) {
1122
- const { id = "loading", ...config } = selectPageLoading(definition) ?? {};
1123
- return Object.freeze({
1124
- config,
1125
- id,
1126
- use: function useDefinedLoading(overrides = {}, options = {}) {
1127
- return useLoading(
1128
- { ...config, ...selectPageLoading(overrides) },
1129
- options
1130
- );
1131
- }
1132
- });
1133
- }
1134
- var loadingModule = defineModule({
1135
- id: "loading",
1136
- context: LoadingContext,
1137
- Provider: LoadingProvider,
1138
- Overlay: LoadingOverlay,
1139
- registry: {
1140
- cleanupDelayMs: 600,
1141
- keyPolicy: "singleton",
1142
- lifecycle: "graceful",
1143
- singletonKey: LOADING_REGISTRY_KEY
1144
- },
1145
- page: {
1146
- select: (config) => selectPageLoading(config.loading),
1147
- entries: (slice) => [
1148
- { key: LOADING_REGISTRY_KEY, value: slice }
1149
- ],
1150
- use: useLoadingPage
1151
- }
1152
- });
1153
-
1154
- export { DEFAULT_LOADING_STATE, DEFAULT_LOADING_STATE_WITH_PAGE, INERT_LOADING_ACTIONS, LOADING_REGISTRY_KEY, LoadingContext, LoadingOverlay, LoadingProvider, NOOP_LOADING_STORE, calculateRemainingMinDuration, defineLoading, loadingModule, loadingTheme, normalizeLoadingOptions, resolveLoadingState, selectPageLoading, useLoading, useLoadingActions, useLoadingOverlayModel, useLoadingRegistration, useLoadingState, useOptionalLoadingActions, useOptionalLoadingState };
2
+ export { DEFAULT_LOADING_STATE, DEFAULT_LOADING_STATE_WITH_PAGE, INERT_LOADING_ACTIONS, LOADING_REGISTRY_KEY, LoadingContext, LoadingOverlay, LoadingProvider, NOOP_LOADING_STORE, calculateRemainingMinDuration, defineLoading, loadingModule, loadingTheme, normalizeLoadingOptions, resolveLoadingState, selectPageLoading, useLoading, useLoadingActions, useLoadingOverlayModel, useLoadingRegistration, useLoadingState, useOptionalLoadingActions, useOptionalLoadingState } from '../../chunk-XASQT4CQ.js';
3
+ import '../../chunk-7TAVYJ3A.js';
4
+ import '../../chunk-GF7TUX5I.js';
5
+ import '../../chunk-TV3WEF5G.js';
6
+ import '../../chunk-3BUP64Q6.js';
1155
7
  //# sourceMappingURL=index.js.map
1156
8
  //# sourceMappingURL=index.js.map