@omerdlw/base-framework 1.0.5 → 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 (232) 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 -20019
  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 +12 -4
  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 -753
  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 -12130
  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/context.d.ts.map +1 -1
  146. package/dist/modules/dock/surface/hooks.d.ts +10 -23
  147. package/dist/modules/dock/surface/hooks.d.ts.map +1 -1
  148. package/dist/modules/dock/surface/machine.d.ts +4 -3
  149. package/dist/modules/dock/surface/machine.d.ts.map +1 -1
  150. package/dist/modules/dock/surface/stack.d.ts.map +1 -1
  151. package/dist/modules/dock/types.d.ts +158 -3
  152. package/dist/modules/dock/types.d.ts.map +1 -1
  153. package/dist/modules/index.js +16 -17873
  154. package/dist/modules/index.js.map +1 -1
  155. package/dist/modules/loading/constants.d.ts +1 -1
  156. package/dist/modules/loading/constants.d.ts.map +1 -1
  157. package/dist/modules/loading/context.d.ts +1 -1
  158. package/dist/modules/loading/hooks.d.ts +1 -1
  159. package/dist/modules/loading/index.js +5 -1153
  160. package/dist/modules/loading/index.js.map +1 -1
  161. package/dist/modules/loading/types.d.ts +2 -2
  162. package/dist/modules/media/context.d.ts +1 -1
  163. package/dist/modules/media/index.js +3 -570
  164. package/dist/modules/media/index.js.map +1 -1
  165. package/dist/modules/media/types.d.ts +2 -2
  166. package/dist/modules/modal/constants.d.ts +2 -2
  167. package/dist/modules/modal/constants.d.ts.map +1 -1
  168. package/dist/modules/modal/context.d.ts +1 -1
  169. package/dist/modules/modal/hooks.d.ts +3 -3
  170. package/dist/modules/modal/index.js +8 -2355
  171. package/dist/modules/modal/index.js.map +1 -1
  172. package/dist/modules/modal/motion.d.ts +3 -8
  173. package/dist/modules/modal/motion.d.ts.map +1 -1
  174. package/dist/modules/modal/overlay.d.ts.map +1 -1
  175. package/dist/modules/modal/types.d.ts +21 -0
  176. package/dist/modules/modal/types.d.ts.map +1 -1
  177. package/dist/modules/notification/constants.d.ts +2 -2
  178. package/dist/modules/notification/constants.d.ts.map +1 -1
  179. package/dist/modules/notification/context.d.ts +1 -1
  180. package/dist/modules/notification/hooks.d.ts +1 -1
  181. package/dist/modules/notification/index.js +4 -828
  182. package/dist/modules/notification/index.js.map +1 -1
  183. package/dist/modules/notification/motion.d.ts +1 -7
  184. package/dist/modules/notification/motion.d.ts.map +1 -1
  185. package/dist/modules/notification/overlay.d.ts.map +1 -1
  186. package/dist/modules/notification/types.d.ts +9 -1
  187. package/dist/modules/notification/types.d.ts.map +1 -1
  188. package/dist/overlay-TZ6L52A5.js +9 -0
  189. package/dist/overlay-TZ6L52A5.js.map +1 -0
  190. package/dist/provider.d.ts +1 -1
  191. package/dist/provider.d.ts.map +1 -1
  192. package/dist/provider.js +6 -1968
  193. package/dist/provider.js.map +1 -1
  194. package/dist/result.js +2 -63
  195. package/dist/result.js.map +1 -1
  196. package/dist/theme.d.ts +45 -8
  197. package/dist/theme.d.ts.map +1 -1
  198. package/dist/theme.js +3 -41
  199. package/dist/theme.js.map +1 -1
  200. package/dist/tokens/index.d.ts +1 -0
  201. package/dist/tokens/index.d.ts.map +1 -1
  202. package/dist/tokens/index.js +126 -155
  203. package/dist/tokens/index.js.map +1 -1
  204. package/dist/tokens/motion-config.d.ts +44 -0
  205. package/dist/tokens/motion-config.d.ts.map +1 -0
  206. package/dist/tokens/motion.d.ts +23 -174
  207. package/dist/tokens/motion.d.ts.map +1 -1
  208. package/dist/utils/index.js +4 -82
  209. package/dist/utils/index.js.map +1 -1
  210. package/dist/utils/report.d.ts.map +1 -1
  211. package/docs/README.md +1 -0
  212. package/docs/architecture-and-rules.md +4 -3
  213. package/docs/core-engine.md +7 -10
  214. package/docs/getting-started.md +4 -2
  215. package/docs/modules/ambient.md +194 -80
  216. package/docs/modules/background.md +3 -3
  217. package/docs/modules/context-menu.md +2 -2
  218. package/docs/modules/dock.md +8 -5
  219. package/docs/modules/modal.md +2 -2
  220. package/docs/modules/notification.md +2 -2
  221. package/docs/theming.md +81 -9
  222. package/package.json +22 -5
  223. package/templates/AGENTS.md +1 -1
  224. package/templates/motion/background.ts +17 -0
  225. package/templates/motion/context-menu.ts +63 -0
  226. package/templates/motion/dock.ts +327 -0
  227. package/templates/motion/modal.ts +79 -0
  228. package/templates/motion/notification.ts +27 -0
  229. package/templates/motion/tokens.ts +47 -0
  230. package/templates/tsconfig.json +7 -0
  231. package/dist/modules/ambient/color.d.ts +0 -16
  232. package/dist/modules/ambient/color.d.ts.map +0 -1
package/dist/provider.js CHANGED
@@ -1,1971 +1,9 @@
1
1
  "use client";
2
- import React, { createContext, useContext, useMemo, useState, createElement, Fragment as Fragment$1, useRef, useCallback, useEffect, isValidElement } from 'react';
3
- import * as TooltipPrimitive from '@radix-ui/react-tooltip';
4
- import { usePathname } from 'next/navigation';
5
- import { Icon as Icon$1 } from '@iconify-icon/react';
6
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
-
8
- // src/error/constants.ts
9
- var ERROR_MESSAGES = Object.freeze({
10
- GLOBAL_TITLE: "Something went wrong",
11
- GLOBAL_MSG: "We ran into an unexpected problem. Please try again",
12
- MODULE_TITLE: "Something went wrong",
13
- MODULE_MSG: "This part of the app isn't working right now. Please try again",
14
- COMPONENT_MSG: "This section couldn't be loaded. Please try again",
15
- FALLBACK_TITLE: "Something went wrong",
16
- FALLBACK_MSG: "This section couldn't be loaded. Please try again"
17
- });
18
- var MAX_CONTEXT = 10;
19
- var MAX_FINGERPRINTS = 100;
20
- var DEFAULT_DEDUPE_WINDOW = 6e4;
21
- var ERROR_LISTENER_CONFIG = Object.freeze({
22
- maxErrors: 10,
23
- throttle: 2e3,
24
- ignored: Object.freeze([
25
- /ResizeObserver loop/i,
26
- /Network request failed/i,
27
- /Loading chunk/i,
28
- /Unexpected end of input/i,
29
- /Failed to fetch/i,
30
- /Script error/i,
31
- /HTTP\s*404/i
32
- ])
33
- });
34
-
35
- // src/error/utils.ts
36
- var IS_BROWSER = typeof window !== "undefined";
37
- var HAS_NAVIGATOR = typeof navigator !== "undefined";
38
- var getRuntimePath = () => typeof window !== "undefined" ? window.location.pathname : null;
39
- var getUserAgent = () => typeof navigator !== "undefined" ? navigator.userAgent : null;
40
- function createErrorContext({
41
- errorInfo,
42
- name,
43
- title,
44
- variant
45
- }) {
46
- return {
47
- componentStack: errorInfo?.componentStack || null,
48
- route: getRuntimePath(),
49
- userAgent: getUserAgent(),
50
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
51
- name: name || title || "ErrorBoundary",
52
- variant: variant || "default",
53
- source: "ErrorBoundary"
54
- };
55
- }
56
- function normalizeSampleRate(value) {
57
- const sampleRate = Number(value);
58
- return Number.isFinite(sampleRate) ? Math.min(1, Math.max(0, sampleRate)) : 1;
59
- }
60
- function normalizeDedupeWindow(value) {
61
- const dedupeWindow = Number(value);
62
- return Number.isFinite(dedupeWindow) ? Math.max(0, dedupeWindow) : DEFAULT_DEDUPE_WINDOW;
63
- }
64
- function getBrowserEnvironment(route) {
65
- return {
66
- route: route || (IS_BROWSER ? window.location.pathname : null),
67
- userAgent: HAS_NAVIGATOR ? navigator.userAgent : null,
68
- platform: HAS_NAVIGATOR ? navigator.platform : null,
69
- language: HAS_NAVIGATOR ? navigator.language : null,
70
- online: HAS_NAVIGATOR ? navigator.onLine : true,
71
- url: IS_BROWSER ? window.location.href : null
72
- };
73
- }
74
- function fingerprint(error, context = {}) {
75
- const stackTop = typeof context.componentStack === "string" ? context.componentStack.split("\n").find(Boolean) || "" : "";
76
- const errObj = error;
77
- const errorMessage = (errObj?.message || String(error || "")).slice(0, 100);
78
- const errorName = errObj?.name || "UnknownError";
79
- const route = context.route || "";
80
- return [stackTop, errorMessage, errorName, route].filter(Boolean).join("::");
81
- }
82
- function createReport(error, {
83
- context = {},
84
- tags = {}
85
- } = {}) {
86
- const errObj = error;
87
- return {
88
- error: {
89
- message: errObj?.message || String(error),
90
- stack: errObj?.stack || null,
91
- name: errObj?.name || "UnknownError"
92
- },
93
- fingerprint: fingerprint(error, context),
94
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
95
- environment: getBrowserEnvironment(context.route),
96
- componentStack: context.componentStack || null,
97
- context,
98
- tags
99
- };
100
- }
101
- function getErrorMessage(error) {
102
- if (!error) return "";
103
- if (typeof error === "string") return error.trim();
104
- if (error instanceof Error) return error.message.trim();
105
- const errObj = error;
106
- return String(errObj?.message || errObj?.toString?.() || error).trim();
107
- }
108
- function shouldIgnoreError(error) {
109
- if (!error) return true;
110
- const errWithNotFound = error;
111
- if (typeof errWithNotFound?.isNotFound === "function" && errWithNotFound.isNotFound()) {
112
- return true;
113
- }
114
- const message = getErrorMessage(error);
115
- return ERROR_LISTENER_CONFIG.ignored.some((pattern) => pattern.test(message));
116
- }
117
-
118
- // src/error/reporter.ts
119
- var IS_PRODUCTION = process.env.NODE_ENV === "production";
120
- var IS_BROWSER2 = typeof window !== "undefined";
121
- var ErrorReporter = class {
122
- handlers = [];
123
- context = {};
124
- tags = {};
125
- seen = /* @__PURE__ */ new Set();
126
- enabled;
127
- sampleRate;
128
- beforeSend;
129
- dedupeWindow;
130
- constructor(options = {}) {
131
- this.enabled = options.enabled ?? true;
132
- this.sampleRate = normalizeSampleRate(options.sampleRate ?? 1);
133
- this.beforeSend = options.beforeSend || null;
134
- this.dedupeWindow = normalizeDedupeWindow(
135
- options.deduplicateWindow ?? DEFAULT_DEDUPE_WINDOW
136
- );
137
- }
138
- addHandler(handler) {
139
- if (typeof handler?.handle === "function") {
140
- this.handlers.push(handler);
141
- }
142
- return this;
143
- }
144
- removeHandler(name) {
145
- this.handlers = this.handlers.filter((handler) => handler.name !== name);
146
- return this;
147
- }
148
- setContext(key, value) {
149
- if (Object.hasOwn(this.context, key) || Object.keys(this.context).length < MAX_CONTEXT) {
150
- this.context[key] = value;
151
- }
152
- return this;
153
- }
154
- setTag(key, value) {
155
- this.tags[key] = String(value);
156
- return this;
157
- }
158
- captureError(error, extraContext = {}) {
159
- if (!this.enabled || Math.random() > this.sampleRate) return;
160
- this.ensureDefaultHandlers();
161
- const context = { ...this.context, ...extraContext };
162
- let report2 = createReport(error, { context, tags: { ...this.tags } });
163
- const dedupeKey = report2.fingerprint;
164
- if (this.seen.has(dedupeKey)) return;
165
- if (this.seen.size >= MAX_FINGERPRINTS) {
166
- const first = this.seen.keys().next().value;
167
- if (first) this.seen.delete(first);
168
- }
169
- this.seen.add(dedupeKey);
170
- setTimeout(() => this.seen.delete(dedupeKey), this.dedupeWindow);
171
- if (typeof this.beforeSend === "function") {
172
- try {
173
- const transformed = this.beforeSend(report2);
174
- if (!transformed) return;
175
- report2 = transformed;
176
- } catch {
177
- }
178
- }
179
- this.handlers.forEach((handler) => {
180
- try {
181
- handler.handle(report2);
182
- } catch {
183
- }
184
- });
185
- return report2;
186
- }
187
- captureMessage(message, level = "info", context = {}) {
188
- const error = new Error(message);
189
- error.name = "Message";
190
- return this.captureError(error, { ...context, level });
191
- }
192
- ensureDefaultHandlers() {
193
- if (this.handlers.length || !IS_BROWSER2) return;
194
- this.handlers.push(createConsoleHandler());
195
- if (window.Sentry) {
196
- const sentryHandler = createSentryHandler(window.Sentry);
197
- if (sentryHandler.name === "sentry") {
198
- this.handlers.push(sentryHandler);
199
- }
200
- }
201
- }
202
- };
203
- var instance = null;
204
- function getErrorReporter(options = {}) {
205
- if (!instance) {
206
- instance = new ErrorReporter(options);
207
- }
208
- return instance;
209
- }
210
- function createConsoleHandler() {
211
- return {
212
- name: "console",
213
- handle(report2) {
214
- if (IS_PRODUCTION) return;
215
- console.error("[ErrorReporter]", {
216
- error: report2.error.message,
217
- fingerprint: report2.fingerprint,
218
- route: report2.environment.route
219
- });
220
- }
221
- };
222
- }
223
- function createSentryHandler(Sentry) {
224
- const sentryObj = Sentry;
225
- if (!sentryObj || typeof sentryObj.captureException !== "function" || typeof sentryObj.withScope !== "function") {
226
- return createConsoleHandler();
227
- }
228
- return {
229
- name: "sentry",
230
- handle(report2) {
231
- sentryObj.withScope((scope) => {
232
- if (report2.fingerprint) scope.setFingerprint([report2.fingerprint]);
233
- if (report2.user) scope.setUser(report2.user);
234
- if (report2.tags && typeof report2.tags === "object") {
235
- Object.entries(report2.tags).forEach(
236
- ([key, value]) => scope.setTag(key, String(value))
237
- );
238
- }
239
- if (report2.environment)
240
- scope.setContext("environment", report2.environment);
241
- if (report2.context) scope.setContext("custom", report2.context);
242
- if (report2.componentStack)
243
- scope.setExtra("componentStack", report2.componentStack);
244
- const error = new Error(report2.error.message);
245
- error.name = report2.error.name || "Error";
246
- error.stack = report2.error.stack || void 0;
247
- sentryObj.captureException(error);
248
- });
249
- }
250
- };
251
- }
252
-
253
- // src/utils/report.ts
254
- var sink = null;
255
- function report(scope, error, level = "error") {
256
- if (sink) {
257
- try {
258
- sink(scope, error, level);
259
- return;
260
- } catch {
261
- }
262
- }
263
- if (process.env.NODE_ENV === "production" && typeof window !== "undefined") {
264
- return;
265
- }
266
- console[level](`[${scope}]`, error);
267
- }
268
- function setReportSink(next) {
269
- sink = next;
270
- return () => {
271
- if (sink === next) sink = null;
272
- };
273
- }
274
-
275
- // src/events.ts
276
- var EVENT_TYPES = Object.freeze({
277
- API_UNAUTHORIZED: "API_UNAUTHORIZED",
278
- STATE_CHANGE: "STATE_CHANGE",
279
- API_ERROR: "API_ERROR",
280
- APP_ERROR: "APP_ERROR"
281
- });
282
- var EventEmitter = class {
283
- events = /* @__PURE__ */ new Map();
284
- debounceTimers = /* @__PURE__ */ new Map();
285
- subscribe(event, callback) {
286
- if (typeof event !== "string" || !event || typeof callback !== "function") {
287
- return () => {
288
- };
289
- }
290
- const listeners = this.events.get(event) || /* @__PURE__ */ new Set();
291
- listeners.add(callback);
292
- this.events.set(event, listeners);
293
- return () => {
294
- listeners.delete(callback);
295
- if (listeners.size === 0) this.events.delete(event);
296
- };
297
- }
298
- emit(event, payload) {
299
- const listeners = this.events.get(event);
300
- if (!listeners || listeners.size === 0) return;
301
- const snapshot = Array.from(listeners);
302
- for (const callback of snapshot) {
303
- try {
304
- callback(payload);
305
- } catch (error) {
306
- report(`Event listener (${String(event)})`, error);
307
- }
308
- }
309
- }
310
- emitDebounced(event, payload, waitMs = 100) {
311
- const existing = this.debounceTimers.get(event);
312
- if (existing) clearTimeout(existing);
313
- const timer = setTimeout(() => {
314
- this.debounceTimers.delete(event);
315
- this.emit(event, payload);
316
- }, waitMs);
317
- this.debounceTimers.set(event, timer);
318
- }
319
- cancelDebounced(event) {
320
- if (event) {
321
- const timer = this.debounceTimers.get(event);
322
- if (timer) {
323
- clearTimeout(timer);
324
- this.debounceTimers.delete(event);
325
- }
326
- } else {
327
- for (const timer of this.debounceTimers.values()) {
328
- clearTimeout(timer);
329
- }
330
- this.debounceTimers.clear();
331
- }
332
- }
333
- unsubscribeAll(event) {
334
- this.cancelDebounced(event);
335
- if (event) this.events.delete(event);
336
- else this.events.clear();
337
- }
338
- hasListeners(event) {
339
- return Boolean(this.events.get(event)?.size);
340
- }
341
- getListenerCount(event) {
342
- return this.events.get(event)?.size || 0;
343
- }
344
- getAllEvents() {
345
- return [...this.events.keys()];
346
- }
347
- };
348
- var GLOBAL_EVENTS_KEY = /* @__PURE__ */ Symbol.for("__base_framework_global_events__");
349
- var _global = globalThis;
350
- var globalEvents = _global[GLOBAL_EVENTS_KEY] ?? (_global[GLOBAL_EVENTS_KEY] = new EventEmitter());
351
- function Icon({
352
- className = "center",
353
- color,
354
- icon,
355
- onClick,
356
- size = 20,
357
- style,
358
- ...props
359
- }) {
360
- return /* @__PURE__ */ jsx(
361
- Icon$1,
362
- {
363
- className,
364
- height: size,
365
- icon,
366
- onClick,
367
- style: { color, ...style },
368
- width: size,
369
- ...props
370
- }
371
- );
372
- }
373
- Icon.displayName = "Icon";
374
- function Button({
375
- ref,
376
- children,
377
- className,
378
- disabled = false,
379
- loading = false,
380
- type = "button",
381
- ...props
382
- }) {
383
- return /* @__PURE__ */ jsx(
384
- "button",
385
- {
386
- ref,
387
- type,
388
- disabled: disabled || loading,
389
- "aria-busy": loading ? true : void 0,
390
- className,
391
- ...props,
392
- children
393
- }
394
- );
395
- }
396
- Button.displayName = "Button";
397
-
398
- // src/kernel/constants.ts
399
- var DEFAULT_SOURCE = "dynamic";
400
- var REGISTRY_SOURCES = Object.freeze({
401
- STATIC: "static",
402
- DYNAMIC: "dynamic",
403
- USER: "user"
404
- });
405
- var REGISTRY_LIFECYCLES = Object.freeze({
406
- IMMEDIATE: "immediate",
407
- GRACEFUL: "graceful",
408
- PERSISTENT: "persistent",
409
- ROUTE: "route"
410
- });
411
- var REGISTRY_VALIDATION_MODES = Object.freeze({
412
- WARN: "warn",
413
- STRICT: "strict"
414
- });
415
- var REGISTRY_METADATA_KEYS = Object.freeze([
416
- "cleanup",
417
- "cleanupDelayMs",
418
- "instanceId",
419
- "lifecycle",
420
- "priority",
421
- "source",
422
- "scope",
423
- "validation"
424
- ]);
425
- var REGISTRY_SOURCE_PRIORITY = Object.freeze({
426
- [REGISTRY_SOURCES.STATIC]: 100,
427
- [REGISTRY_SOURCES.DYNAMIC]: 200,
428
- [REGISTRY_SOURCES.USER]: 300
429
- });
430
- var REGISTRY_SOURCE_RANK = Object.freeze({
431
- [REGISTRY_SOURCES.STATIC]: 10,
432
- [REGISTRY_SOURCES.DYNAMIC]: 20,
433
- [REGISTRY_SOURCES.USER]: 30
434
- });
435
- var REGISTRY_LIFECYCLE_VALUES = new Set(
436
- Object.values(REGISTRY_LIFECYCLES)
437
- );
438
- var REGISTRY_METADATA_KEY_SET = new Set(
439
- REGISTRY_METADATA_KEYS
440
- );
441
- var REGISTRY_SCOPE_KINDS = Object.freeze({
442
- APP: "app",
443
- SESSION: "session",
444
- ROUTE: "route",
445
- INSTANCE: "instance",
446
- WORKSPACE: "workspace"
447
- });
448
- var DEFAULT_REGISTRY_SCOPE = REGISTRY_SCOPE_KINDS.APP;
449
- function getOrCreateGlobalContext(name, defaultValue) {
450
- const sym = /* @__PURE__ */ Symbol.for(`@omerdlw/base-framework/context/${name}`);
451
- const store = globalThis;
452
- if (!store[sym]) {
453
- store[sym] = createContext(defaultValue);
454
- }
455
- return store[sym];
456
- }
457
-
458
- // src/utils/string.ts
459
- function trimToNull(value) {
460
- if (value === null || value === void 0) return null;
461
- const trimmed = String(value).trim();
462
- return trimmed.length > 0 ? trimmed : null;
463
- }
464
-
465
- // src/utils/object.ts
466
- function isObject(value) {
467
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
468
- }
469
- function isPlainObject(value) {
470
- if (!isObject(value)) return false;
471
- const proto = Object.getPrototypeOf(value);
472
- return proto === Object.prototype || proto === null;
473
- }
474
- function shallowEqual(a, b) {
475
- if (Object.is(a, b)) return true;
476
- if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) {
477
- return false;
478
- }
479
- const keysA = Object.keys(a);
480
- const keysB = Object.keys(b);
481
- if (keysA.length !== keysB.length) return false;
482
- for (const key of keysA) {
483
- if (!Object.prototype.hasOwnProperty.call(b, key) || !Object.is(
484
- a[key],
485
- b[key]
486
- )) {
487
- return false;
488
- }
489
- }
490
- return true;
491
- }
492
-
493
- // src/utils/user-message.ts
494
- var USER_MESSAGES = Object.freeze({
495
- generic: "Something went wrong. Please try again",
496
- network: "You appear to be offline. Check your connection and try again",
497
- timeout: "That took too long. Please try again",
498
- unauthorized: "Your session has expired. Please sign in again",
499
- forbidden: "You don't have permission to do that",
500
- notFound: "We couldn't find what you were looking for",
501
- rateLimited: "Too many attempts. Please wait a moment and try again",
502
- server: "We're having trouble on our end. Please try again in a moment"
503
- });
504
- var UserError = class extends Error {
505
- status;
506
- constructor(message, status) {
507
- super(message);
508
- this.name = "UserError";
509
- this.status = status;
510
- }
511
- };
512
- var NETWORK_FAILURE = /failed to fetch|network|load failed|fetch failed/i;
513
- function readField(source, field, type) {
514
- const value = source?.[field];
515
- return typeof value === type ? value : void 0;
516
- }
517
- function readPayloadMessage(error) {
518
- const payload = error?.payload;
519
- const message = readField(payload, "error", "string")?.trim();
520
- return message || void 0;
521
- }
522
- function toUserMessage(error, { codes, fallback = USER_MESSAGES.generic } = {}) {
523
- if (typeof error === "string") return error.trim() || fallback;
524
- if (!error || typeof error !== "object") return fallback;
525
- if (error instanceof UserError) {
526
- if (error.status === 401) return USER_MESSAGES.unauthorized;
527
- return error.message || fallback;
528
- }
529
- if (error.name === "AbortError") return fallback;
530
- const code = readField(error, "code", "string");
531
- if (code && codes?.[code]) return codes[code];
532
- const status = readField(error, "status", "number");
533
- if (status === 401) return USER_MESSAGES.unauthorized;
534
- if (status === 429) return USER_MESSAGES.rateLimited;
535
- if (status === 408 || status === 504) return USER_MESSAGES.timeout;
536
- if (status !== void 0 && status >= 500) return USER_MESSAGES.server;
537
- if (status !== void 0 && status >= 400) {
538
- const authored = readPayloadMessage(error);
539
- if (authored) return authored;
540
- if (status === 403) return USER_MESSAGES.forbidden;
541
- if (status === 404) return USER_MESSAGES.notFound;
542
- return fallback;
543
- }
544
- const isOffline = typeof navigator !== "undefined" && navigator.onLine === false;
545
- if (isOffline || NETWORK_FAILURE.test(error.message ?? "") && (error instanceof TypeError || /fetch/i.test(error.name))) {
546
- return USER_MESSAGES.network;
547
- }
548
- return fallback;
549
- }
550
-
551
- // src/utils/store.ts
552
- function freezeStoreSnapshot(state) {
553
- if (process.env.NODE_ENV === "production" || !state || typeof state !== "object") {
554
- return state;
555
- }
556
- const seen = /* @__PURE__ */ new WeakSet();
557
- const freeze = (value) => {
558
- if (seen.has(value) || Object.isFrozen(value)) return;
559
- seen.add(value);
560
- const prototype = Object.getPrototypeOf(value);
561
- if (Array.isArray(value) || prototype === Object.prototype || prototype === null) {
562
- for (const key of Reflect.ownKeys(value)) {
563
- const descriptor = Object.getOwnPropertyDescriptor(value, key);
564
- if (descriptor && "value" in descriptor && descriptor.value !== null) {
565
- if (typeof descriptor.value === "object") freeze(descriptor.value);
566
- }
567
- }
568
- }
569
- Object.freeze(value);
570
- };
571
- freeze(state);
572
- return state;
573
- }
574
- function createStore(initialState, { freezeSnapshots = true } = {}) {
575
- const listeners = /* @__PURE__ */ new Set();
576
- const prepare = freezeSnapshots ? freezeStoreSnapshot : (state) => state;
577
- let snapshot = prepare(initialState);
578
- const publish = (nextStateOrUpdater) => {
579
- const nextState = typeof nextStateOrUpdater === "function" ? nextStateOrUpdater(snapshot) : nextStateOrUpdater;
580
- if (Object.is(snapshot, nextState)) return false;
581
- snapshot = prepare(nextState);
582
- for (const listener of listeners) {
583
- try {
584
- listener();
585
- } catch (error) {
586
- report("CoreStore subscriber", error, "warn");
587
- }
588
- }
589
- return true;
590
- };
591
- const setState = (updater) => {
592
- if (typeof updater === "function") {
593
- return publish(updater);
594
- }
595
- if (snapshot && typeof snapshot === "object" && updater && typeof updater === "object") {
596
- return publish({ ...snapshot, ...updater });
597
- }
598
- return publish(updater);
599
- };
600
- return Object.freeze({
601
- getSnapshot() {
602
- return snapshot;
603
- },
604
- publish,
605
- setState,
606
- subscribe(listener) {
607
- if (typeof listener !== "function") return () => {
608
- };
609
- listeners.add(listener);
610
- return () => listeners.delete(listener);
611
- }
612
- });
613
- }
614
-
615
- // src/kernel/utils.ts
616
- function hasOwnProperty(target, key) {
617
- return Object.prototype.hasOwnProperty.call(target, key);
618
- }
619
- function parseFiniteNumber(value) {
620
- const parsed = Number(value);
621
- return Number.isFinite(parsed) ? parsed : null;
622
- }
623
- function getValidString(value, fallback = null) {
624
- return trimToNull(value) ?? fallback;
625
- }
626
- function resolveInstanceId(value) {
627
- return isObject(value) && typeof value.instanceId === "string" ? value.instanceId : null;
628
- }
629
- function getSourceRank(source) {
630
- return REGISTRY_SOURCE_RANK[source] ?? 0;
631
- }
632
- function resolveRegisterInput(sourceOrOptions, optionsArg) {
633
- if (typeof sourceOrOptions === "string") {
634
- return {
635
- source: sourceOrOptions,
636
- options: isObject(optionsArg) ? optionsArg : {}
637
- };
638
- }
639
- if (isObject(sourceOrOptions)) {
640
- return {
641
- source: typeof sourceOrOptions.source === "string" ? sourceOrOptions.source : DEFAULT_SOURCE,
642
- options: sourceOrOptions
643
- };
644
- }
645
- return {
646
- source: DEFAULT_SOURCE,
647
- options: isObject(optionsArg) ? optionsArg : {}
648
- };
649
- }
650
- function resolveScope(options) {
651
- return typeof options?.scope === "string" && options.scope.trim() ? options.scope.trim() : DEFAULT_REGISTRY_SCOPE;
652
- }
653
- function resolveUnregisterInput(sourceOrOptions) {
654
- if (typeof sourceOrOptions === "string") {
655
- return { instanceId: null, scope: null, source: sourceOrOptions };
656
- }
657
- if (isObject(sourceOrOptions)) {
658
- return {
659
- instanceId: resolveInstanceId(sourceOrOptions),
660
- scope: typeof sourceOrOptions.scope === "string" && sourceOrOptions.scope.trim() ? sourceOrOptions.scope.trim() : null,
661
- source: typeof sourceOrOptions.source === "string" ? sourceOrOptions.source : DEFAULT_SOURCE
662
- };
663
- }
664
- return { instanceId: null, scope: null, source: DEFAULT_SOURCE };
665
- }
666
-
667
- // src/kernel/schema.ts
668
- function validateRegistryMetadata(metadata) {
669
- if (metadata === void 0 || metadata === null)
670
- return { issues: [], valid: true };
671
- if (!isObject(metadata))
672
- return { issues: ["registry metadata must be an object"], valid: false };
673
- const issues = [];
674
- Object.keys(metadata).forEach((key) => {
675
- if (!REGISTRY_METADATA_KEY_SET.has(key))
676
- issues.push(`unknown registry metadata field: ${key}`);
677
- });
678
- if (metadata.source !== void 0 && !getValidString(metadata.source))
679
- issues.push("source must be a non-empty string");
680
- if (metadata.instanceId !== void 0 && !getValidString(metadata.instanceId))
681
- issues.push("instanceId must be a non-empty string");
682
- if (metadata.scope !== void 0 && !getValidString(metadata.scope))
683
- issues.push("scope must be a non-empty string");
684
- if (metadata.priority !== void 0 && parseFiniteNumber(metadata.priority) === null)
685
- issues.push("priority must be a finite number");
686
- if (metadata.cleanupDelayMs !== void 0) {
687
- const delay = parseFiniteNumber(metadata.cleanupDelayMs);
688
- if (delay === null || delay < 0)
689
- issues.push("cleanupDelayMs must be a non-negative finite number");
690
- }
691
- const lifecycle = metadata.lifecycle ?? metadata.cleanup;
692
- if (lifecycle !== void 0 && !REGISTRY_LIFECYCLE_VALUES.has(String(lifecycle))) {
693
- issues.push(
694
- `lifecycle must be one of: ${[...REGISTRY_LIFECYCLE_VALUES].join(", ")}`
695
- );
696
- }
697
- if (metadata.validation !== void 0 && !Object.values(REGISTRY_VALIDATION_MODES).includes(
698
- metadata.validation
699
- )) {
700
- issues.push(
701
- `validation must be one of: ${Object.values(REGISTRY_VALIDATION_MODES).join(", ")}`
702
- );
703
- }
704
- return { issues, valid: issues.length === 0 };
705
- }
706
- function validateRegistryKey(type, key, definitions) {
707
- const definition = definitions.get(type);
708
- const issues = [];
709
- if (!definition) issues.push(`unknown registry type: ${String(type)}`);
710
- if (!getValidString(key))
711
- return {
712
- issues: [...issues, "key must be a non-empty string"],
713
- valid: false
714
- };
715
- const normalizedKey = String(key).trim();
716
- if (definition?.keyPolicy === "singleton") {
717
- const expectedKey = definition.singletonKey;
718
- if (expectedKey && normalizedKey !== expectedKey)
719
- issues.push(`${type} key must be ${expectedKey}`);
720
- } else if (definition?.keyPolicy === "path") {
721
- if (!normalizedKey.startsWith("/"))
722
- issues.push(`${type} key must be an absolute path`);
723
- } else if (definition?.keyPolicy === "route") {
724
- if (!normalizedKey.startsWith("/") && !definition.reservedKeys?.includes(normalizedKey)) {
725
- issues.push(`${type} key must be a route path or a reserved route key`);
726
- }
727
- }
728
- return { issues, valid: issues.length === 0 };
729
- }
730
- function validateRegistryValue(type, key, value, definitions) {
731
- const definition = definitions.get(type);
732
- const issues = [...validateRegistryKey(type, key, definitions).issues];
733
- const valueKind = definition?.valueKind ?? "object";
734
- if (definition && valueKind === "object" && !isPlainObject(value)) {
735
- issues.push(`${type} values must be plain objects`);
736
- }
737
- if (definition && valueKind === "component" && typeof value !== "function" && !isPlainObject(value)) {
738
- issues.push(
739
- `${type} values must be component functions or component objects`
740
- );
741
- }
742
- const validation = definition?.validate?.(value);
743
- if (validation && !validation.valid && Array.isArray(validation.issues)) {
744
- issues.push(...validation.issues);
745
- }
746
- return { issues, valid: issues.length === 0 };
747
- }
748
-
749
- // src/kernel/operations.ts
750
- function createInitialRegistriesFor(definitions) {
751
- return Object.fromEntries(
752
- Array.from(definitions.keys(), (type) => [type, {}])
753
- );
754
- }
755
- function buildSourceRecord({
756
- source,
757
- value,
758
- instanceId = null,
759
- priority,
760
- timestamp,
761
- sequence,
762
- scope = DEFAULT_REGISTRY_SCOPE
763
- }) {
764
- return {
765
- updatedAt: timestamp,
766
- sequence: Number.isFinite(sequence) ? sequence : timestamp,
767
- instanceId: typeof instanceId === "string" ? instanceId : null,
768
- priority,
769
- value,
770
- source,
771
- scope
772
- };
773
- }
774
- function createRecordKey(source, instanceId = null, scope = DEFAULT_REGISTRY_SCOPE) {
775
- if (scope === DEFAULT_REGISTRY_SCOPE) {
776
- if (typeof instanceId === "string" && instanceId.length > 0) {
777
- return `instance:${JSON.stringify([source, instanceId])}`;
778
- }
779
- return `source:${JSON.stringify(source)}`;
780
- }
781
- if (typeof instanceId === "string" && instanceId.length > 0) {
782
- return `instance:${JSON.stringify([scope, source, instanceId])}`;
783
- }
784
- return `source:${JSON.stringify([scope, source])}`;
785
- }
786
- function getSourceRecords(entry, source, scope = null) {
787
- if (!entry) return [];
788
- return Object.entries(entry).map(([recordKey, rawRecord]) => ({
789
- recordKey,
790
- record: toSourceRecord(rawRecord, recordKey)
791
- })).filter(
792
- ({ record }) => record?.source === source && (scope === null || record.scope === scope)
793
- );
794
- }
795
- function getSourceRecord(entry, source, instanceId = null, scope = DEFAULT_REGISTRY_SCOPE) {
796
- const recordKey = createRecordKey(source, instanceId, scope);
797
- return toSourceRecord(entry?.[recordKey], source);
798
- }
799
- function resolveRecordPriority(options, source) {
800
- if (isObject(options) && hasOwnProperty(options, "priority")) {
801
- const parsedPriority = Number(options.priority);
802
- if (Number.isFinite(parsedPriority)) return parsedPriority;
803
- }
804
- return REGISTRY_SOURCE_PRIORITY[source] ?? 0;
805
- }
806
- function toSourceRecord(rawValue, source = DEFAULT_SOURCE) {
807
- if (rawValue === void 0) return null;
808
- const rawRecord = rawValue;
809
- const isWrappedRecord = isObject(rawValue) && hasOwnProperty(rawRecord, "value") && hasOwnProperty(rawRecord, "updatedAt") && hasOwnProperty(rawRecord, "priority") && hasOwnProperty(rawRecord, "source");
810
- if (isWrappedRecord) {
811
- const parsedPriority = Number(rawRecord.priority);
812
- return {
813
- updatedAt: Number(rawRecord.updatedAt) || 0,
814
- sequence: Number(rawRecord.sequence) || Number(rawRecord.updatedAt) || 0,
815
- instanceId: typeof rawRecord.instanceId === "string" ? rawRecord.instanceId : null,
816
- priority: Number.isFinite(parsedPriority) ? parsedPriority : REGISTRY_SOURCE_PRIORITY[source] ?? 0,
817
- source: typeof rawRecord.source === "string" ? rawRecord.source : source,
818
- scope: typeof rawRecord.scope === "string" ? rawRecord.scope : DEFAULT_REGISTRY_SCOPE,
819
- value: rawRecord.value
820
- };
821
- }
822
- return {
823
- updatedAt: 0,
824
- sequence: 0,
825
- instanceId: null,
826
- priority: REGISTRY_SOURCE_PRIORITY[source] ?? 0,
827
- source,
828
- scope: DEFAULT_REGISTRY_SCOPE,
829
- value: rawValue
830
- };
831
- }
832
- function compareRecords(a, b) {
833
- if (a.priority !== b.priority) return a.priority - b.priority;
834
- const rankDiff = getSourceRank(a.source) - getSourceRank(b.source);
835
- if (rankDiff !== 0) return rankDiff;
836
- return (a.sequence ?? a.updatedAt) - (b.sequence ?? b.updatedAt);
837
- }
838
- function recordsHaveSameValue(prevRecord, nextRecord) {
839
- if (Object.is(prevRecord?.value, nextRecord?.value)) return true;
840
- if (isObject(prevRecord?.value) && isObject(nextRecord?.value)) {
841
- return shallowEqual(prevRecord.value, nextRecord.value);
842
- }
843
- return false;
844
- }
845
- function hasRecordChanged(prevRecord, nextRecord) {
846
- if (!prevRecord) return true;
847
- return prevRecord.priority !== nextRecord.priority || prevRecord.source !== nextRecord.source || prevRecord.instanceId !== nextRecord.instanceId || prevRecord.scope !== nextRecord.scope || !recordsHaveSameValue(prevRecord, nextRecord);
848
- }
849
- function hasAnySourceRecord(entry) {
850
- return Object.values(entry || {}).some(
851
- (rawRecord) => rawRecord !== void 0
852
- );
853
- }
854
- function setSourceRecord(state, type, key, source, record) {
855
- const typeRegistry = state[type] || {};
856
- const currentEntry = typeRegistry[key] || {};
857
- const recordKey = createRecordKey(source, record.instanceId, record.scope);
858
- const prevRecord = toSourceRecord(currentEntry[recordKey], source);
859
- if (!hasRecordChanged(prevRecord, record)) {
860
- return state;
861
- }
862
- return {
863
- ...state,
864
- [type]: {
865
- ...typeRegistry,
866
- [key]: {
867
- ...currentEntry,
868
- [recordKey]: record
869
- }
870
- }
871
- };
872
- }
873
- function removeSourceRecord(state, type, key, source, instanceId = null, scope = null) {
874
- const typeRegistry = state[type];
875
- const currentEntry = typeRegistry?.[key];
876
- if (!typeRegistry || !currentEntry) return state;
877
- let activeRecords = [];
878
- if (typeof instanceId === "string" && instanceId.length > 0 && scope !== null) {
879
- const safeScope = scope || DEFAULT_REGISTRY_SCOPE;
880
- const recordKey = createRecordKey(source, instanceId, safeScope);
881
- const record = getSourceRecord(currentEntry, source, instanceId, safeScope);
882
- if (record) activeRecords.push({ recordKey, record });
883
- } else {
884
- activeRecords = getSourceRecords(currentEntry, source, scope).filter(({ record }) => !instanceId || record?.instanceId === instanceId).filter(
885
- (entry) => Boolean(entry.record)
886
- );
887
- }
888
- if (activeRecords.length === 0) return state;
889
- const nextEntry = { ...currentEntry };
890
- activeRecords.forEach(({ recordKey }) => {
891
- delete nextEntry[recordKey];
892
- });
893
- if (!hasAnySourceRecord(nextEntry)) {
894
- const nextTypeRegistry = { ...typeRegistry };
895
- delete nextTypeRegistry[key];
896
- return { ...state, [type]: nextTypeRegistry };
897
- }
898
- return {
899
- ...state,
900
- [type]: { ...typeRegistry, [key]: nextEntry }
901
- };
902
- }
903
- function resolveEntryValueFor(definitions, type, entry, scope = null) {
904
- if (!entry) return void 0;
905
- const activeRecords = Object.entries(entry).map(([source, rawRecord]) => toSourceRecord(rawRecord, source)).filter(
906
- (record) => record !== null && (scope === null || record.scope === scope)
907
- );
908
- if (activeRecords.length === 0) return void 0;
909
- const merge = definitions.get(type)?.merge;
910
- if (merge) {
911
- const sortedRecords = [...activeRecords].sort(compareRecords);
912
- const mergeCandidate = sortedRecords.every(
913
- (record) => isObject(record.value)
914
- );
915
- if (mergeCandidate) {
916
- const values = sortedRecords.map(
917
- (record) => record.value
918
- );
919
- return merge(values);
920
- }
921
- return sortedRecords[sortedRecords.length - 1].value;
922
- }
923
- return activeRecords.reduce(
924
- (winner, current) => compareRecords(current, winner) > 0 ? current : winner
925
- ).value;
926
- }
927
- function createResolverCacheFor(definitions) {
928
- const entryCache = /* @__PURE__ */ new WeakMap();
929
- return (type, entry, scope = null) => {
930
- if (!entry || typeof entry !== "object") {
931
- return resolveEntryValueFor(definitions, type, entry, scope);
932
- }
933
- let typeCache = entryCache.get(entry);
934
- if (!typeCache) {
935
- typeCache = /* @__PURE__ */ new Map();
936
- entryCache.set(entry, typeCache);
937
- }
938
- const cacheKey = scope || "default";
939
- if (typeCache.has(cacheKey)) return typeCache.get(cacheKey);
940
- const value = resolveEntryValueFor(definitions, type, entry, scope);
941
- typeCache.set(cacheKey, value);
942
- return value;
943
- };
944
- }
945
- function createRegisterOperation(type, key, item, sourceOrOptions, optionsArg, timestamp, sequence = timestamp) {
946
- const { source, options } = resolveRegisterInput(sourceOrOptions, optionsArg);
947
- const instanceId = resolveInstanceId(options);
948
- const scope = resolveScope(options);
949
- return {
950
- kind: "register",
951
- validation: options.validation,
952
- source,
953
- scope,
954
- record: buildSourceRecord({
955
- source,
956
- value: item,
957
- instanceId,
958
- priority: resolveRecordPriority(options, source),
959
- scope,
960
- timestamp,
961
- sequence
962
- }),
963
- instanceId,
964
- type,
965
- key: typeof key === "string" ? key.trim() : key
966
- };
967
- }
968
- function createUnregisterOperation(type, key, sourceOrOptions) {
969
- const { scope, source, instanceId } = resolveUnregisterInput(sourceOrOptions);
970
- return {
971
- kind: "unregister",
972
- instanceId,
973
- scope,
974
- source,
975
- type,
976
- key: typeof key === "string" ? key.trim() : key
977
- };
978
- }
979
- function isValidRegistryTargetFor(definitions, type, key) {
980
- return validateRegistryKey(type, key, definitions).valid;
981
- }
982
- function applyOperationFor(definitions, state, operation) {
983
- if (!isValidRegistryTargetFor(definitions, operation?.type, operation?.key))
984
- return state;
985
- if (operation.kind === "register") {
986
- return setSourceRecord(
987
- state,
988
- operation.type,
989
- operation.key,
990
- operation.source,
991
- operation.record
992
- );
993
- }
994
- if (operation.kind === "unregister") {
995
- return removeSourceRecord(
996
- state,
997
- operation.type,
998
- operation.key,
999
- operation.source,
1000
- operation.instanceId,
1001
- operation.scope
1002
- );
1003
- }
1004
- return state;
1005
- }
1006
- function hasOperationEffectFor(definitions, state, operation) {
1007
- if (!isValidRegistryTargetFor(definitions, operation?.type, operation?.key))
1008
- return false;
1009
- if (operation.kind === "register") {
1010
- const currentRecord = getSourceRecord(
1011
- state[operation.type]?.[operation.key],
1012
- operation.source,
1013
- operation.instanceId,
1014
- operation.scope
1015
- );
1016
- return hasRecordChanged(currentRecord, operation.record);
1017
- }
1018
- if (operation.kind === "unregister") {
1019
- const entry = state[operation.type]?.[operation.key];
1020
- if (typeof operation.instanceId === "string" && operation.instanceId.length > 0) {
1021
- return operation.scope === null ? getSourceRecords(entry, operation.source).some(
1022
- ({ record }) => record?.instanceId === operation.instanceId
1023
- ) : Boolean(
1024
- getSourceRecord(
1025
- entry,
1026
- operation.source,
1027
- operation.instanceId,
1028
- operation.scope
1029
- )
1030
- );
1031
- }
1032
- return getSourceRecords(entry, operation.source, operation.scope).length > 0;
1033
- }
1034
- return false;
1035
- }
1036
- function resolveEffectiveOperationsFor(definitions, state, operations) {
1037
- const effectiveOperations = [];
1038
- let nextState = state;
1039
- operations.forEach((operation) => {
1040
- if (!hasOperationEffectFor(definitions, nextState, operation)) return;
1041
- effectiveOperations.push(operation);
1042
- nextState = applyOperationFor(definitions, nextState, operation);
1043
- });
1044
- return { effectiveOperations, nextState };
1045
- }
1046
- function createRegistryOperations(definitions) {
1047
- return Object.freeze({
1048
- applyOperation: (state, operation) => applyOperationFor(definitions, state, operation),
1049
- createInitialRegistries: () => createInitialRegistriesFor(definitions),
1050
- createResolverCache: () => createResolverCacheFor(definitions),
1051
- hasOperationEffect: (state, operation) => hasOperationEffectFor(definitions, state, operation),
1052
- isRegistryType: (type) => definitions.get(type) !== void 0,
1053
- isValidRegistryTarget: (type, key) => isValidRegistryTargetFor(definitions, type, key),
1054
- resolveEffectiveOperations: (state, operations) => resolveEffectiveOperationsFor(definitions, state, operations),
1055
- resolveEntryValue: (type, entry, scope = null) => resolveEntryValueFor(definitions, type, entry, scope)
1056
- });
1057
- }
1058
-
1059
- // src/kernel/runtime.ts
1060
- function createRegistryTransaction(store, metadata = {}) {
1061
- const operations = [];
1062
- let status = "open";
1063
- const traceId = metadata.traceId || `tx-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
1064
- const ensureOpen = () => status === "open";
1065
- const mergeOptions = (options) => {
1066
- const baseOpts = options && typeof options === "object" ? options : {};
1067
- const needsSource = metadata.source && !baseOpts.source;
1068
- const needsScope = metadata.scope && !baseOpts.scope;
1069
- if (!needsSource && !needsScope) return baseOpts;
1070
- return {
1071
- ...baseOpts,
1072
- ...needsSource ? { source: metadata.source } : {},
1073
- ...needsScope ? { scope: metadata.scope } : {}
1074
- };
1075
- };
1076
- const register = (type, key, value, sourceOrOptions, optionsArg) => {
1077
- if (!ensureOpen()) return { index: -1, status, traceId };
1078
- const options = typeof sourceOrOptions === "string" ? mergeOptions({ ...optionsArg || {}, source: sourceOrOptions }) : mergeOptions(sourceOrOptions);
1079
- operations.push({ key, item: value, options, type });
1080
- return { index: operations.length - 1, status: "queued", traceId };
1081
- };
1082
- const unregister = (type, key, sourceOrOptions) => {
1083
- if (!ensureOpen()) return { index: -1, status, traceId };
1084
- const options = mergeOptions(
1085
- typeof sourceOrOptions === "string" ? { source: sourceOrOptions } : sourceOrOptions
1086
- );
1087
- operations.push({ key, options, type, unregister: true });
1088
- return { index: operations.length - 1, status: "queued", traceId };
1089
- };
1090
- const rollback = (_reason = "manual") => {
1091
- if (!ensureOpen()) return { index: -1, status, traceId };
1092
- status = "rolled-back";
1093
- operations.length = 0;
1094
- return { index: -1, status, traceId };
1095
- };
1096
- const commit = () => {
1097
- if (!ensureOpen()) return { status, traceId };
1098
- status = "committed";
1099
- const result = store.batch((queue) => {
1100
- operations.forEach((op) => {
1101
- if (op.unregister) queue.unregister(op.type, op.key, op.options);
1102
- else queue.register(op.type, op.key, op.item, op.options);
1103
- });
1104
- });
1105
- const applied = typeof result === "number" && Number.isFinite(result) ? result : 0;
1106
- return { applied, queued: operations.length, status, traceId };
1107
- };
1108
- const run = (executor) => {
1109
- if (typeof executor !== "function") {
1110
- rollback("invalid-executor");
1111
- return { status, traceId };
1112
- }
1113
- try {
1114
- executor({ register, unregister });
1115
- return commit();
1116
- } catch (error) {
1117
- rollback(error instanceof Error ? error.message : String(error));
1118
- throw error;
1119
- }
1120
- };
1121
- return {
1122
- commit,
1123
- get operations() {
1124
- return operations.slice();
1125
- },
1126
- register,
1127
- rollback,
1128
- run,
1129
- get status() {
1130
- return status;
1131
- },
1132
- traceId,
1133
- unregister
1134
- };
1135
- }
1136
-
1137
- // src/kernel/store.ts
1138
- var NO_DEFINITIONS = /* @__PURE__ */ new Map();
1139
- function createNoopHandle(status = "rejected", reason = "unknown") {
1140
- const handle = Object.assign(() => false, {
1141
- active: false,
1142
- dispose: () => false,
1143
- instanceId: null,
1144
- key: "",
1145
- priority: 0,
1146
- reason,
1147
- source: "",
1148
- status,
1149
- type: "",
1150
- update: () => handle,
1151
- updatedAt: 0,
1152
- validation: "warn"
1153
- });
1154
- return handle;
1155
- }
1156
- var NOOP_HANDLE = createNoopHandle();
1157
- function isNoopHandle(handle) {
1158
- return handle === NOOP_HANDLE || handle?.status === "rejected" || handle?.status === "ignored";
1159
- }
1160
- function cloneRegistryValue(value, seen = /* @__PURE__ */ new WeakMap()) {
1161
- if (value === null || typeof value !== "object" || isValidElement(value)) {
1162
- return value;
1163
- }
1164
- const prototype = Object.getPrototypeOf(value);
1165
- const isPlainObject2 = !Array.isArray(value) && (prototype === Object.prototype || prototype === null);
1166
- if (!Array.isArray(value) && !isPlainObject2) return value;
1167
- if (seen.has(value)) return seen.get(value);
1168
- const source = value;
1169
- const clone = Array.isArray(value) ? [] : {};
1170
- seen.set(value, clone);
1171
- for (const key in source) {
1172
- if (Object.prototype.hasOwnProperty.call(source, key)) {
1173
- clone[key] = cloneRegistryValue(source[key], seen);
1174
- }
1175
- }
1176
- return clone;
1177
- }
1178
- function normalizeInitialEntries(entries) {
1179
- return (Array.isArray(entries) ? entries : []).filter(
1180
- (entry) => entry?.type && entry?.items && typeof entry.items === "object"
1181
- );
1182
- }
1183
- function createInitialState(ops, definitions, entries) {
1184
- const normalizedEntries = normalizeInitialEntries(entries);
1185
- if (normalizedEntries.length === 0) return ops.createInitialRegistries();
1186
- const timestamp = Date.now();
1187
- let sequence = 0;
1188
- let state = ops.createInitialRegistries();
1189
- normalizedEntries.forEach((entry) => {
1190
- const source = entry.source || REGISTRY_SOURCES.STATIC;
1191
- const options = {
1192
- ...entry.options || {},
1193
- instanceId: entry.instanceId || entry.options?.instanceId || "registry-initial"
1194
- };
1195
- Object.entries(entry.items).forEach(([key, value]) => {
1196
- const validation = validateRegistration(
1197
- definitions,
1198
- entry.type,
1199
- key,
1200
- value,
1201
- source,
1202
- options
1203
- );
1204
- if (!validation.valid) return;
1205
- const operation = createRegisterOperation(
1206
- entry.type,
1207
- key,
1208
- cloneRegistryValue(value),
1209
- source,
1210
- options,
1211
- timestamp,
1212
- ++sequence
1213
- );
1214
- if (ops.hasOperationEffect(state, operation)) {
1215
- state = ops.applyOperation(state, operation);
1216
- }
1217
- });
1218
- });
1219
- return state;
1220
- }
1221
- function notifyListeners(listeners) {
1222
- if (!listeners) return;
1223
- for (const listener of listeners) {
1224
- try {
1225
- listener();
1226
- } catch (error) {
1227
- report("Registry listener", error);
1228
- }
1229
- }
1230
- }
1231
- function getOrCreateKeyListeners(listenersByType, type, key) {
1232
- let listeners = listenersByType.get(type);
1233
- if (!listeners) {
1234
- listeners = /* @__PURE__ */ new Map();
1235
- listenersByType.set(type, listeners);
1236
- }
1237
- let keyListeners = listeners.get(key);
1238
- if (!keyListeners) {
1239
- keyListeners = /* @__PURE__ */ new Set();
1240
- listeners.set(key, keyListeners);
1241
- }
1242
- return keyListeners;
1243
- }
1244
- function resolveRegistrationOptions(sourceOrOptions, optionsArg) {
1245
- if (sourceOrOptions && typeof sourceOrOptions === "object")
1246
- return sourceOrOptions;
1247
- return optionsArg && typeof optionsArg === "object" ? optionsArg : {};
1248
- }
1249
- function validateRegistration(definitions, type, key, value, sourceOrOptions, optionsArg) {
1250
- const options = resolveRegistrationOptions(sourceOrOptions, optionsArg);
1251
- const metadataValidation = validateRegistryMetadata(options);
1252
- const isStrict = options.validation === REGISTRY_VALIDATION_MODES.STRICT;
1253
- if (!metadataValidation.valid && isStrict) {
1254
- return {
1255
- issues: metadataValidation.issues,
1256
- reason: "invalid-metadata",
1257
- valid: false
1258
- };
1259
- }
1260
- const validation = validateRegistryValue(type, key, value, definitions);
1261
- if (validation.valid) return { valid: true };
1262
- if (!isStrict) {
1263
- report(`Registry ${type} "${key}" is invalid`, validation.issues, "warn");
1264
- }
1265
- return {
1266
- issues: validation.issues,
1267
- reason: "invalid-value",
1268
- valid: !isStrict
1269
- };
1270
- }
1271
- function createRegistrationHandle(store, operation) {
1272
- let disposed = false;
1273
- const dispose = (reason = "manual") => {
1274
- if (disposed) return false;
1275
- disposed = true;
1276
- return store.dispose(operation, reason);
1277
- };
1278
- const handle = ((reason) => dispose(reason));
1279
- handle.dispose = dispose;
1280
- handle.update = (value, options = {}) => {
1281
- if (disposed || !store.isCurrent(operation)) return NOOP_HANDLE;
1282
- const nextHandle = store.register(
1283
- operation.type,
1284
- operation.key,
1285
- value,
1286
- operation.source,
1287
- {
1288
- ...typeof options === "object" ? options : {},
1289
- instanceId: operation.instanceId,
1290
- priority: operation.record.priority,
1291
- ...operation.scope ? { scope: operation.scope } : {},
1292
- ...operation.validation ? { validation: operation.validation } : {}
1293
- }
1294
- );
1295
- if (isNoopHandle(nextHandle)) return handle;
1296
- disposed = true;
1297
- return nextHandle;
1298
- };
1299
- Object.defineProperties(handle, {
1300
- active: {
1301
- enumerable: true,
1302
- get: () => !disposed && store.isCurrent(operation)
1303
- },
1304
- instanceId: { enumerable: true, value: operation.instanceId },
1305
- key: { enumerable: true, value: operation.key },
1306
- priority: { enumerable: true, value: operation.record.priority },
1307
- source: { enumerable: true, value: operation.source },
1308
- status: {
1309
- enumerable: true,
1310
- get: () => disposed ? "disposed" : store.isCurrent(operation) ? "active" : "superseded"
1311
- },
1312
- type: { enumerable: true, value: operation.type },
1313
- updatedAt: { enumerable: true, value: operation.record.updatedAt },
1314
- validation: { enumerable: true, value: operation.validation || "warn" }
1315
- });
1316
- return handle;
1317
- }
1318
- function prepareRegisterOperation(ops, definitions, type, key, item, sourceOrOptions, optionsArg, timestamp, sequence) {
1319
- if (!ops.isValidRegistryTarget(type, key)) {
1320
- return { rejected: createNoopHandle("rejected", "invalid-target") };
1321
- }
1322
- const validation = validateRegistration(
1323
- definitions,
1324
- type,
1325
- key,
1326
- item,
1327
- sourceOrOptions,
1328
- optionsArg
1329
- );
1330
- if (!validation.valid) {
1331
- return { rejected: createNoopHandle("rejected", validation.reason) };
1332
- }
1333
- return {
1334
- operation: createRegisterOperation(
1335
- type,
1336
- key,
1337
- cloneRegistryValue(item),
1338
- sourceOrOptions,
1339
- optionsArg,
1340
- timestamp,
1341
- sequence
1342
- )
1343
- };
1344
- }
1345
- function createRegistryStore(initialEntries = [], definitions = NO_DEFINITIONS) {
1346
- const ops = createRegistryOperations(definitions);
1347
- let registries = createInitialState(ops, definitions, initialEntries);
1348
- let sequence = normalizeInitialEntries(initialEntries).reduce(
1349
- (count, entry) => count + Object.keys(entry.items).length,
1350
- 0
1351
- );
1352
- const listenersByType = /* @__PURE__ */ new Map();
1353
- const entrySnapshots = /* @__PURE__ */ new Map();
1354
- const valueSnapshots = /* @__PURE__ */ new Map();
1355
- const resolveCachedValue = ops.createResolverCache();
1356
- const subscribe = (type, key, listener) => {
1357
- const keyListeners = getOrCreateKeyListeners(
1358
- listenersByType,
1359
- type,
1360
- key ?? null
1361
- );
1362
- keyListeners.add(listener);
1363
- return () => {
1364
- keyListeners.delete(listener);
1365
- if (keyListeners.size > 0) return;
1366
- const listeners = listenersByType.get(type);
1367
- if (listeners) {
1368
- listeners.delete(key ?? null);
1369
- if (listeners.size === 0) listenersByType.delete(type);
1370
- }
1371
- };
1372
- };
1373
- const commit = (nextState, operations = []) => {
1374
- if (registries === nextState) return;
1375
- const previousState = registries;
1376
- registries = nextState;
1377
- const changedKeysByType = /* @__PURE__ */ new Map();
1378
- for (const operation of operations) {
1379
- if (!ops.isValidRegistryTarget(operation?.type, operation?.key)) continue;
1380
- let keys = changedKeysByType.get(operation.type);
1381
- if (!keys) {
1382
- keys = /* @__PURE__ */ new Set();
1383
- changedKeysByType.set(operation.type, keys);
1384
- }
1385
- keys.add(operation.key);
1386
- }
1387
- for (const [type, changedKeys] of changedKeysByType) {
1388
- const previousRegistry = previousState[type] || {};
1389
- const nextRegistry = nextState[type] || {};
1390
- const typeListeners = listenersByType.get(type);
1391
- let typeChanged = false;
1392
- if (!typeListeners) continue;
1393
- for (const key of changedKeys) {
1394
- if (previousRegistry[key] === nextRegistry[key]) continue;
1395
- typeChanged = true;
1396
- notifyListeners(typeListeners.get(key));
1397
- }
1398
- if (typeChanged) {
1399
- notifyListeners(typeListeners.get(null));
1400
- }
1401
- }
1402
- };
1403
- const isCurrent = (operation) => {
1404
- const entry = registries[operation.type]?.[operation.key];
1405
- const recordKey = createRecordKey(
1406
- operation.source,
1407
- operation.instanceId,
1408
- operation.scope
1409
- );
1410
- return entry?.[recordKey] === operation.record;
1411
- };
1412
- const dispose = (operation, _reason = "manual") => {
1413
- if (!isCurrent(operation)) return false;
1414
- const unregisterOperation = createUnregisterOperation(
1415
- operation.type,
1416
- operation.key,
1417
- {
1418
- source: operation.source,
1419
- instanceId: operation.instanceId,
1420
- scope: operation.scope
1421
- }
1422
- );
1423
- if (!ops.hasOperationEffect(registries, unregisterOperation)) return false;
1424
- commit(ops.applyOperation(registries, unregisterOperation), [
1425
- unregisterOperation
1426
- ]);
1427
- return true;
1428
- };
1429
- const register = (type, key, item, sourceOrOptions = DEFAULT_SOURCE, optionsArg = {}) => {
1430
- const prepared = prepareRegisterOperation(
1431
- ops,
1432
- definitions,
1433
- type,
1434
- key,
1435
- item,
1436
- sourceOrOptions,
1437
- optionsArg,
1438
- Date.now(),
1439
- ++sequence
1440
- );
1441
- if ("rejected" in prepared) return prepared.rejected;
1442
- const { operation } = prepared;
1443
- if (!ops.hasOperationEffect(registries, operation)) {
1444
- return createNoopHandle("ignored", "unchanged");
1445
- }
1446
- commit(ops.applyOperation(registries, operation), [operation]);
1447
- return createRegistrationHandle(store, operation);
1448
- };
1449
- const unregister = (type, key, sourceOrOptions = DEFAULT_SOURCE) => {
1450
- if (!ops.isValidRegistryTarget(type, key)) return;
1451
- const operation = createUnregisterOperation(type, key, sourceOrOptions);
1452
- if (!ops.hasOperationEffect(registries, operation)) return;
1453
- commit(ops.applyOperation(registries, operation), [operation]);
1454
- };
1455
- const batch = (executor) => {
1456
- if (typeof executor !== "function") return 0;
1457
- const timestamp = Date.now();
1458
- const operations = [];
1459
- const queue = {
1460
- register: (type, key, item, sourceOrOptions = DEFAULT_SOURCE, optionsArg = {}) => {
1461
- const prepared = prepareRegisterOperation(
1462
- ops,
1463
- definitions,
1464
- type,
1465
- key,
1466
- item,
1467
- sourceOrOptions,
1468
- optionsArg,
1469
- timestamp,
1470
- ++sequence
1471
- );
1472
- if ("rejected" in prepared) return prepared.rejected;
1473
- operations.push(prepared.operation);
1474
- return createRegistrationHandle(store, prepared.operation);
1475
- },
1476
- unregister: (type, key, sourceOrOptions = DEFAULT_SOURCE) => {
1477
- if (!ops.isValidRegistryTarget(type, key)) return;
1478
- operations.push(createUnregisterOperation(type, key, sourceOrOptions));
1479
- }
1480
- };
1481
- executor(queue);
1482
- if (operations.length === 0) return 0;
1483
- const { effectiveOperations, nextState } = ops.resolveEffectiveOperations(
1484
- registries,
1485
- operations
1486
- );
1487
- if (effectiveOperations.length === 0) return 0;
1488
- commit(nextState, effectiveOperations);
1489
- return effectiveOperations.length;
1490
- };
1491
- const getSnapshot = (type, key, scope = null) => {
1492
- const entry = registries[type]?.[key];
1493
- let snapshots = valueSnapshots.get(type);
1494
- if (!snapshots) {
1495
- snapshots = /* @__PURE__ */ new Map();
1496
- valueSnapshots.set(type, snapshots);
1497
- }
1498
- const cacheKey = scope === null ? key : `${scope}\0${key}`;
1499
- if (entry === void 0) {
1500
- snapshots.delete(cacheKey);
1501
- return void 0;
1502
- }
1503
- const cached = snapshots.get(cacheKey);
1504
- if (cached && cached.entry === entry) return cached.value;
1505
- const value = resolveCachedValue(type, entry, scope);
1506
- snapshots.set(cacheKey, { entry, value });
1507
- return value;
1508
- };
1509
- const getEntriesSnapshot = (type, scope = null) => {
1510
- const typeRegistry = registries[type] || {};
1511
- const cacheKey = `${type}::${scope ?? "null"}`;
1512
- const cached = entrySnapshots.get(cacheKey);
1513
- if (cached?.typeRegistry === typeRegistry) return cached.value;
1514
- const resolved = {};
1515
- for (const key in typeRegistry) {
1516
- if (Object.prototype.hasOwnProperty.call(typeRegistry, key)) {
1517
- const value = resolveCachedValue(type, typeRegistry[key], scope);
1518
- if (value !== void 0) resolved[key] = value;
1519
- }
1520
- }
1521
- const finalValue = Object.freeze(resolved);
1522
- entrySnapshots.set(cacheKey, { typeRegistry, value: finalValue });
1523
- return finalValue;
1524
- };
1525
- const store = {
1526
- batch,
1527
- dispose,
1528
- getEntriesSnapshot,
1529
- getSnapshot,
1530
- isCurrent,
1531
- register,
1532
- subscribe,
1533
- transaction: (executor, metadata = {}) => createRegistryTransaction(store, metadata).run(executor),
1534
- unregister
1535
- };
1536
- return store;
1537
- }
1538
- var RegistryContext = getOrCreateGlobalContext(
1539
- "RegistryContext",
1540
- null
1541
- );
1542
- function RegistryProvider({
1543
- children,
1544
- definitions,
1545
- initialEntries = []
1546
- }) {
1547
- const [store] = useState(
1548
- () => createRegistryStore(initialEntries, definitions)
1549
- );
1550
- const contextValue = useMemo(
1551
- () => ({
1552
- actions: {
1553
- batch: store.batch,
1554
- register: store.register,
1555
- transaction: store.transaction,
1556
- unregister: store.unregister
1557
- },
1558
- subscription: {
1559
- getEntriesSnapshot: store.getEntriesSnapshot,
1560
- getSnapshot: store.getSnapshot,
1561
- subscribe: store.subscribe
1562
- }
1563
- }),
1564
- [store]
1565
- );
1566
- return /* @__PURE__ */ jsx(RegistryContext, { value: contextValue, children });
1567
- }
1568
- var EMPTY_MODULES = Object.freeze([]);
1569
- var PassthroughBoundary = ({ children }) => children;
1570
- var ModuleHostContext = getOrCreateGlobalContext("ModuleHostContext", null);
1571
- var MODULE_ID_PATTERN = /^[a-z][a-zA-Z0-9]*$/;
1572
- function sortModules(modules) {
1573
- const byId = /* @__PURE__ */ new Map();
1574
- for (const coreModule of modules) {
1575
- if (!MODULE_ID_PATTERN.test(coreModule.id)) {
1576
- throw new Error(
1577
- `[Core] Invalid module id "${coreModule.id}": use a camelCase name such as "contextMenu".`
1578
- );
1579
- }
1580
- if (byId.has(coreModule.id)) {
1581
- throw new Error(`[Core] Module "${coreModule.id}" is installed twice.`);
1582
- }
1583
- byId.set(coreModule.id, coreModule);
1584
- }
1585
- const sorted = [];
1586
- const state = /* @__PURE__ */ new Map();
1587
- const visit = (coreModule, path) => {
1588
- const current = state.get(coreModule.id);
1589
- if (current === "done") return;
1590
- if (current === "visiting") {
1591
- throw new Error(
1592
- `[Core] Module dependency cycle: ${[...path, coreModule.id].join(" -> ")}`
1593
- );
1594
- }
1595
- state.set(coreModule.id, "visiting");
1596
- for (const id of coreModule.uses ?? []) {
1597
- const dependency = byId.get(id);
1598
- if (dependency) visit(dependency, [...path, coreModule.id]);
1599
- }
1600
- state.set(coreModule.id, "done");
1601
- sorted.push(coreModule);
1602
- };
1603
- modules.forEach((coreModule) => visit(coreModule, []));
1604
- return sorted;
1605
- }
1606
- function createModuleRegistryDefinitions(modules) {
1607
- const definitions = /* @__PURE__ */ new Map();
1608
- for (const coreModule of modules) {
1609
- if (coreModule.registry)
1610
- definitions.set(coreModule.id, coreModule.registry);
1611
- }
1612
- return definitions;
1613
- }
1614
- function createPageControllerStore() {
1615
- const listeners = /* @__PURE__ */ new Set();
1616
- let stack = [];
1617
- const notify = () => {
1618
- listeners.forEach((listener) => {
1619
- try {
1620
- listener();
1621
- } catch (error) {
1622
- report("Page controller listener", error);
1623
- }
1624
- });
1625
- };
1626
- return {
1627
- getSnapshot() {
1628
- const top = stack[stack.length - 1];
1629
- return top?.controllerRef?.current || null;
1630
- },
1631
- notify,
1632
- register(id, controllerRef) {
1633
- stack = stack.filter((item) => item.id !== id);
1634
- stack.push({ controllerRef, id });
1635
- notify();
1636
- },
1637
- subscribe(listener) {
1638
- listeners.add(listener);
1639
- return () => {
1640
- listeners.delete(listener);
1641
- };
1642
- },
1643
- unregister(id) {
1644
- stack = stack.filter((item) => item.id !== id);
1645
- notify();
1646
- }
1647
- };
1648
- }
1649
- var fallbackStandaloneStore = createPageControllerStore();
1650
- getOrCreateGlobalContext(
1651
- "PageControllerContext",
1652
- null
1653
- );
1654
- var PageControllerStoreContext = getOrCreateGlobalContext(
1655
- "PageControllerStoreContext",
1656
- fallbackStandaloneStore
1657
- );
1658
- function PageControllerProvider({ children }) {
1659
- const [store] = useState(
1660
- () => createPageControllerStore()
1661
- );
1662
- return /* @__PURE__ */ jsx(PageControllerStoreContext, { value: store, children });
1663
- }
1664
- function warnMissingPeers(modules) {
1665
- const installed = new Set(modules.map((coreModule) => coreModule.id));
1666
- for (const { id, uses } of modules) {
1667
- const missing = (uses ?? []).filter((peer) => !installed.has(peer));
1668
- if (missing.length > 0) {
1669
- report(
1670
- `Module "${id}" runs without its optional peers`,
1671
- missing.join(", "),
1672
- "warn"
1673
- );
1674
- }
1675
- }
1676
- }
1677
- function createModuleHost(modules, Boundary) {
1678
- const sorted = sortModules(modules);
1679
- if (process.env.NODE_ENV !== "production") warnMissingPeers(sorted);
1680
- return {
1681
- Boundary,
1682
- byId: new Map(sorted.map((coreModule) => [coreModule.id, coreModule])),
1683
- definitions: createModuleRegistryDefinitions(sorted),
1684
- modules: Object.freeze(sorted)
1685
- };
1686
- }
1687
- function ModuleHost({
1688
- boundary = PassthroughBoundary,
1689
- children,
1690
- modules = EMPTY_MODULES,
1691
- registryEntries
1692
- }) {
1693
- const [host] = useState(() => createModuleHost(modules, boundary));
1694
- const { Boundary } = host;
1695
- const content = /* @__PURE__ */ jsxs(Fragment, { children: [
1696
- host.modules.map(
1697
- ({ Backdrop, id }) => Backdrop ? /* @__PURE__ */ jsx(Boundary, { name: id, children: /* @__PURE__ */ jsx(Backdrop, {}) }, id) : null
1698
- ),
1699
- children,
1700
- host.modules.map(
1701
- ({ Overlay, id }) => Overlay ? /* @__PURE__ */ jsx(Boundary, { name: id, children: /* @__PURE__ */ jsx(Overlay, {}) }, id) : null
1702
- )
1703
- ] });
1704
- const tree = host.modules.reduceRight(
1705
- (inner, { Provider: Provider2 }) => Provider2 ? /* @__PURE__ */ jsx(Provider2, { children: inner }) : inner,
1706
- content
1707
- );
1708
- return /* @__PURE__ */ jsx(
1709
- RegistryProvider,
1710
- {
1711
- definitions: host.definitions,
1712
- initialEntries: registryEntries,
1713
- children: /* @__PURE__ */ jsx(ModuleHostContext, { value: host, children: /* @__PURE__ */ jsx(PageControllerProvider, { children: tree }) })
1714
- }
1715
- );
1716
- }
1717
- createStore(void 0);
1718
- function Compose({ providers, children }) {
1719
- return providers.reduceRight(
1720
- (acc, entry) => {
1721
- if (Array.isArray(entry)) {
1722
- const [Component2, props] = entry;
1723
- return createElement(Component2, props, acc);
1724
- }
1725
- const Component = entry;
1726
- return createElement(Component, null, acc);
1727
- },
1728
- createElement(Fragment$1, null, children)
1729
- );
1730
- }
1731
-
1732
- // src/theme.tsx
1733
- function defineThemeSpec(id) {
1734
- return Object.freeze({ id });
1735
- }
1736
- var EMPTY = /* @__PURE__ */ new Map();
1737
- var ThemeContext = getOrCreateGlobalContext("ThemeContext", EMPTY);
1738
- function useTheme(spec) {
1739
- const config = useContext(ThemeContext).get(spec.id);
1740
- if (!config) {
1741
- throw new Error(
1742
- `Theme "${spec.id}" is missing. Ensure its theme configuration is provided to <ThemeProvider themes={[...]}> (e.g. in src/config/ or your theme setup).`
1743
- );
1744
- }
1745
- return {
1746
- slots: config.slots,
1747
- styles: config.styles ?? {}
1748
- };
1749
- }
1750
-
1751
- // src/error/theme.ts
1752
- var errorTheme = defineThemeSpec("error");
1753
- var ActionButton = Button;
1754
- function DefaultErrorFallback({
1755
- error,
1756
- message,
1757
- resetError,
1758
- title
1759
- }) {
1760
- const theme = useTheme(errorTheme);
1761
- return /* @__PURE__ */ jsxs("div", { className: theme.slots.screen, children: [
1762
- /* @__PURE__ */ jsx("div", { className: theme.slots.icon, children: /* @__PURE__ */ jsx(Icon, { icon: "solar:danger-circle-bold", size: 30 }) }),
1763
- /* @__PURE__ */ jsx("h3", { className: theme.slots.title, children: message || toUserMessage(error, { fallback: ERROR_MESSAGES.FALLBACK_MSG }) }),
1764
- /* @__PURE__ */ jsx(
1765
- ActionButton,
1766
- {
1767
- className: theme.slots.retryButton,
1768
- onClick: resetError,
1769
- type: "button",
1770
- children: "Try again"
1771
- }
1772
- )
1773
- ] });
1774
- }
1775
- var ErrorBoundaryCore = class extends React.Component {
1776
- constructor(props) {
1777
- super(props);
1778
- this.state = {
1779
- error: null,
1780
- errorInfo: null,
1781
- hasError: false,
1782
- lastResetKey: props.resetKey
1783
- };
1784
- }
1785
- static getDerivedStateFromError(error) {
1786
- return { error, hasError: true };
1787
- }
1788
- static getDerivedStateFromProps(props, state) {
1789
- if (props.resetKey !== state.lastResetKey) {
1790
- return {
1791
- error: null,
1792
- errorInfo: null,
1793
- hasError: false,
1794
- lastResetKey: props.resetKey
1795
- };
1796
- }
1797
- return null;
1798
- }
1799
- componentDidCatch(error, errorInfo) {
1800
- this.setState({ errorInfo });
1801
- const { message, name, onError, silent, title, variant } = this.props;
1802
- const context = createErrorContext({ errorInfo, name, title, variant });
1803
- try {
1804
- onError?.(error, errorInfo, context);
1805
- } catch (callbackError) {
1806
- report("ErrorBoundary onError callback", callbackError, "warn");
1807
- }
1808
- if (!silent) {
1809
- globalEvents.emit(EVENT_TYPES.APP_ERROR, {
1810
- error,
1811
- errorInfo,
1812
- message: message || toUserMessage(error),
1813
- resetError: this.resetError
1814
- });
1815
- }
1816
- try {
1817
- const reporter = getErrorReporter();
1818
- reporter?.captureError?.(error, context);
1819
- } catch (reportingError) {
1820
- report("ErrorBoundary reporting", reportingError, "warn");
1821
- }
1822
- }
1823
- resetError = () => {
1824
- this.setState({
1825
- error: null,
1826
- errorInfo: null,
1827
- hasError: false
1828
- });
1829
- this.props.onReset?.();
1830
- };
1831
- render() {
1832
- if (!this.state.hasError) return this.props.children;
1833
- const { fallback, message, title } = this.props;
1834
- const { error } = this.state;
1835
- if (typeof fallback === "function") {
1836
- return fallback({ error, resetError: this.resetError });
1837
- }
1838
- if (fallback) {
1839
- return fallback;
1840
- }
1841
- return /* @__PURE__ */ jsx(
1842
- DefaultErrorFallback,
1843
- {
1844
- error,
1845
- message,
1846
- resetError: this.resetError,
1847
- title
1848
- }
1849
- );
1850
- }
1851
- };
1852
- function GlobalError({ children, fallback, onReset }) {
1853
- const pathname = usePathname();
1854
- return /* @__PURE__ */ jsx(
1855
- ErrorBoundaryCore,
1856
- {
1857
- fallback,
1858
- message: ERROR_MESSAGES.GLOBAL_MSG,
1859
- onReset,
1860
- resetKey: pathname,
1861
- title: ERROR_MESSAGES.GLOBAL_TITLE,
1862
- variant: "full",
1863
- children
1864
- }
1865
- );
1866
- }
1867
- function ModuleError({
1868
- children,
1869
- fallback,
1870
- name,
1871
- onReset
1872
- }) {
1873
- return /* @__PURE__ */ jsx(
1874
- ErrorBoundaryCore,
1875
- {
1876
- fallback,
1877
- message: ERROR_MESSAGES.MODULE_MSG,
1878
- name,
1879
- onReset,
1880
- title: name ? `${name} Error` : ERROR_MESSAGES.MODULE_TITLE,
1881
- variant: "module",
1882
- children
1883
- }
1884
- );
1885
- }
1886
- function GlobalErrorListener() {
1887
- const lastError = useRef(0);
1888
- const count = useRef(0);
1889
- const shown = useRef(/* @__PURE__ */ new Set());
1890
- const handleError = useCallback((error, source = "runtime") => {
1891
- if (shouldIgnoreError(error)) return;
1892
- const now = Date.now();
1893
- if (count.current >= ERROR_LISTENER_CONFIG.maxErrors) return;
1894
- if (now - lastError.current < ERROR_LISTENER_CONFIG.throttle) return;
1895
- const message = getErrorMessage(error);
1896
- const key = message || String(error);
1897
- if (shown.current.has(key)) return;
1898
- shown.current.add(key);
1899
- lastError.current = now;
1900
- count.current += 1;
1901
- try {
1902
- const reporter = getErrorReporter();
1903
- reporter?.captureError?.(error, {
1904
- globalListener: true,
1905
- source
1906
- });
1907
- } catch (reportingError) {
1908
- report("GlobalError reporting", reportingError, "warn");
1909
- }
1910
- globalEvents.emit(EVENT_TYPES.APP_ERROR, {
1911
- error,
1912
- message: toUserMessage(error)
1913
- });
1914
- }, []);
1915
- useEffect(() => {
1916
- const removeSink = setReportSink((scope, error, level) => {
1917
- try {
1918
- getErrorReporter().captureError(error, { level, scope });
1919
- } catch {
1920
- }
1921
- });
1922
- const onError = (event) => handleError(event.error || event.message, "window.onerror");
1923
- const onRejection = (event) => handleError(event.reason, "unhandledrejection");
1924
- window.addEventListener("error", onError);
1925
- window.addEventListener("unhandledrejection", onRejection);
1926
- return () => {
1927
- removeSink();
1928
- window.removeEventListener("error", onError);
1929
- window.removeEventListener("unhandledrejection", onRejection);
1930
- };
1931
- }, [handleError]);
1932
- return null;
1933
- }
1934
- function CoreProvider({
1935
- children,
1936
- modules,
1937
- overlays,
1938
- providers,
1939
- registryEntries,
1940
- slots,
1941
- tooltip = true
1942
- }) {
1943
- const tooltipConfig = useMemo(
1944
- () => tooltip === false ? null : {
1945
- delayDuration: typeof tooltip === "object" && tooltip.delayDuration || 300,
1946
- skipDelayDuration: typeof tooltip === "object" && tooltip.skipDelayDuration || 150
1947
- },
1948
- [tooltip]
1949
- );
1950
- const providerPipeline = useMemo(
1951
- () => [
1952
- GlobalError,
1953
- ...tooltipConfig ? [[TooltipPrimitive.Provider, tooltipConfig]] : [],
1954
- [ModuleHost, { boundary: ModuleError, modules, registryEntries }],
1955
- ...providers ?? []
1956
- ],
1957
- [modules, providers, registryEntries, tooltipConfig]
1958
- );
1959
- return /* @__PURE__ */ jsxs(Compose, { providers: providerPipeline, children: [
1960
- slots?.beforeContent,
1961
- children,
1962
- slots?.afterContent,
1963
- overlays,
1964
- slots?.overlays,
1965
- /* @__PURE__ */ jsx(GlobalErrorListener, {})
1966
- ] });
1967
- }
1968
-
1969
- export { CoreProvider };
2
+ export { CoreProvider } from './chunk-K676GL7Z.js';
3
+ import './chunk-JELG4JLT.js';
4
+ import './chunk-7TAVYJ3A.js';
5
+ import './chunk-GF7TUX5I.js';
6
+ import './chunk-TV3WEF5G.js';
7
+ import './chunk-3BUP64Q6.js';
1970
8
  //# sourceMappingURL=provider.js.map
1971
9
  //# sourceMappingURL=provider.js.map