@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
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/kernel/context-registry.ts","../../../src/utils/object.ts","../../../src/utils/report.ts","../../../src/utils/store.ts","../../../src/hooks/use-required-context.ts","../../../src/hooks/use-store.ts","../../../src/kernel/module.tsx","../../../src/theme.tsx","../../../src/modules/ambient/constants.ts","../../../src/modules/ambient/color.ts","../../../src/modules/ambient/extractor.ts","../../../src/modules/ambient/dom.ts","../../../src/modules/background/state.ts","../../../src/modules/background/context.tsx","../../../src/modules/background/hooks.ts","../../../src/modules/ambient/context.tsx","../../../src/modules/ambient/hooks.ts","../../../src/modules/ambient/module.tsx"],"names":["avgL","prev","curr","next","useContext","useState","useMemo","jsx","useRef","useEffect","use"],"mappings":"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","file":"index.js","sourcesContent":["import { createContext, type Context } from \"react\";\n\nexport function getOrCreateGlobalContext<T>(\n name: string,\n defaultValue: T,\n): Context<T> {\n const sym = Symbol.for(`@omerdlw/base-framework/context/${name}`);\n const store = globalThis as unknown as Record<symbol, Context<T>>;\n if (!store[sym]) {\n store[sym] = createContext<T>(defaultValue);\n }\n return store[sym];\n}\n","export function isObject(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function isPlainObject(\n value: unknown,\n): value is Record<string, unknown> {\n if (!isObject(value)) return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\nexport function shallowEqual(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (\n typeof a !== \"object\" ||\n a === null ||\n typeof b !== \"object\" ||\n b === null\n ) {\n return false;\n }\n\n const keysA = Object.keys(a as object);\n const keysB = Object.keys(b as object);\n\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (\n !Object.prototype.hasOwnProperty.call(b, key) ||\n !Object.is(\n (a as Record<string, unknown>)[key],\n (b as Record<string, unknown>)[key],\n )\n ) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function toArray<T>(value: T | T[] | null | undefined): T[] {\n if (value === null || value === undefined) return [];\n return Array.isArray(value) ? value : [value];\n}\n","export type ReportLevel = \"error\" | \"warn\";\n\nexport type ReportSink = (\n scope: string,\n error: unknown,\n level: ReportLevel,\n) => void;\n\nlet sink: ReportSink | null = null;\n\nexport function report(\n scope: string,\n error: unknown,\n level: ReportLevel = \"error\",\n): void {\n if (sink) {\n try {\n sink(scope, error, level);\n return;\n } catch {}\n }\n\n if (process.env.NODE_ENV === \"production\" && typeof window !== \"undefined\") {\n return;\n }\n console[level](`[${scope}]`, error);\n}\n\nexport function setReportSink(next: ReportSink): () => void {\n sink = next;\n return () => {\n if (sink === next) sink = null;\n };\n}\n","import { report } from \"./report\";\nexport interface ExternalStore<TState = unknown> {\n readonly getSnapshot: () => TState;\n readonly publish: (\n nextState: TState | ((currentState: TState) => TState),\n ) => boolean;\n readonly setState: (\n updater: Partial<TState> | ((currentState: TState) => TState),\n ) => boolean;\n readonly subscribe: (listener: () => void) => () => void;\n}\n\nfunction freezeStoreSnapshot<TState>(state: TState): TState {\n if (\n process.env.NODE_ENV === \"production\" ||\n !state ||\n typeof state !== \"object\"\n ) {\n return state;\n }\n\n const seen = new WeakSet<object>();\n const freeze = (value: object): void => {\n if (seen.has(value) || Object.isFrozen(value)) return;\n seen.add(value);\n\n const prototype = Object.getPrototypeOf(value);\n if (\n Array.isArray(value) ||\n prototype === Object.prototype ||\n prototype === null\n ) {\n for (const key of Reflect.ownKeys(value)) {\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (descriptor && \"value\" in descriptor && descriptor.value !== null) {\n if (typeof descriptor.value === \"object\") freeze(descriptor.value);\n }\n }\n }\n\n Object.freeze(value);\n };\n\n freeze(state);\n return state;\n}\n\nexport interface CreateStoreOptions {\n freezeSnapshots?: boolean;\n}\n\nexport function createStore<TState = Record<string, unknown>>(\n initialState: TState,\n { freezeSnapshots = true }: CreateStoreOptions = {},\n): ExternalStore<TState> {\n const listeners = new Set<() => void>();\n const prepare = freezeSnapshots\n ? freezeStoreSnapshot\n : <T>(state: T): T => state;\n let snapshot = prepare(initialState);\n\n const publish = (\n nextStateOrUpdater: TState | ((currentState: TState) => TState),\n ): boolean => {\n const nextState =\n typeof nextStateOrUpdater === \"function\"\n ? (nextStateOrUpdater as (currentState: TState) => TState)(snapshot)\n : nextStateOrUpdater;\n if (Object.is(snapshot, nextState)) return false;\n snapshot = prepare(nextState);\n\n for (const listener of listeners) {\n try {\n listener();\n } catch (error) {\n report(\"CoreStore subscriber\", error, \"warn\");\n }\n }\n return true;\n };\n\n const setState = (\n updater: Partial<TState> | ((currentState: TState) => TState),\n ): boolean => {\n if (typeof updater === \"function\") {\n return publish(updater as (currentState: TState) => TState);\n }\n if (\n snapshot &&\n typeof snapshot === \"object\" &&\n updater &&\n typeof updater === \"object\"\n ) {\n return publish({ ...snapshot, ...updater });\n }\n return publish(updater as TState);\n };\n\n return Object.freeze({\n getSnapshot() {\n return snapshot;\n },\n publish,\n setState,\n subscribe(listener: () => void) {\n if (typeof listener !== \"function\") return () => {};\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n });\n}\n","\"use client\";\n\nimport { use, type Context } from \"react\";\n\nexport function useRequiredContext<T>(\n context: Context<T | null>,\n hookName: string,\n providerName: string,\n): T {\n const value = use(context);\n if (value === null) {\n throw new Error(`${hookName} must be used within ${providerName}`);\n }\n return value;\n}\n","\"use client\";\n\nimport { useCallback, useRef, useSyncExternalStore } from \"react\";\nimport { type ExternalStore } from \"../utils\";\n\nexport function useStore<TState, TSlice = TState>(\n store: ExternalStore<TState>,\n selector: (state: TState) => TSlice = (state: TState) =>\n state as unknown as TSlice,\n isEqual: (a: TSlice, b: TSlice) => boolean = Object.is,\n): TSlice {\n const cacheRef = useRef<{\n isEqual: ((a: TSlice, b: TSlice) => boolean) | null;\n selected: TSlice | undefined;\n selector: ((state: TState) => TSlice) | null;\n snapshot: TState | null;\n }>({\n isEqual: null,\n selected: undefined,\n selector: null,\n snapshot: null,\n });\n\n const getSelectedSnapshot = useCallback(() => {\n const snapshot = store.getSnapshot();\n const cache = cacheRef.current;\n if (\n cache.snapshot === snapshot &&\n cache.selector === selector &&\n cache.isEqual === isEqual\n ) {\n return cache.selected as TSlice;\n }\n\n const selected = selector(snapshot);\n if (\n cache.snapshot !== null &&\n cache.isEqual === isEqual &&\n isEqual(cache.selected as TSlice, selected)\n ) {\n cache.snapshot = snapshot;\n cache.selector = selector;\n return cache.selected as TSlice;\n }\n\n cacheRef.current = {\n isEqual,\n selected,\n selector,\n snapshot,\n };\n return selected;\n }, [isEqual, selector, store]);\n\n return useSyncExternalStore(\n store.subscribe,\n getSelectedSnapshot,\n getSelectedSnapshot,\n );\n}\n","\"use client\";\n\nimport { createElement, use, useState, type ReactNode } from \"react\";\nimport { useStore } from \"@/hooks\";\nimport { createStore, type ExternalStore } from \"@/utils\";\nimport {\n EMPTY_MODULES,\n ModuleHostContext,\n PassthroughBoundary,\n createModuleRegistryDefinitions,\n sortModules,\n type BoundaryComponent,\n type ModuleHostValue,\n} from \"./installed\";\nimport { PageControllerProvider } from \"./page-controller\";\nimport { RegistryProvider } from \"./provider\";\nimport type {\n AnyCoreModule,\n AppRegistryEntry,\n CoreModule,\n CoreModules,\n ModuleId,\n ModuleRuntimeOf,\n ModuleStateOf,\n} from \"./types\";\nimport { report } from \"@/utils\";\n\nexport function defineModule<\n TId extends string,\n TRuntime = never,\n TSlice = never,\n TController = never,\n>(\n coreModule: CoreModule<TId, TRuntime, TSlice, TController>,\n): CoreModule<TId, TRuntime, TSlice, TController> {\n return Object.freeze({ ...coreModule });\n}\n\nfunction warnMissingPeers(modules: readonly AnyCoreModule[]): void {\n const installed = new Set(modules.map((coreModule) => coreModule.id));\n for (const { id, uses } of modules) {\n const missing = (uses ?? []).filter((peer) => !installed.has(peer));\n if (missing.length > 0) {\n report(\n `Module \"${id}\" runs without its optional peers`,\n missing.join(\", \"),\n \"warn\",\n );\n }\n }\n}\n\nfunction createModuleHost(\n modules: readonly AnyCoreModule[],\n Boundary: BoundaryComponent,\n): ModuleHostValue {\n const sorted = sortModules(modules);\n if (process.env.NODE_ENV !== \"production\") warnMissingPeers(sorted);\n return {\n Boundary,\n byId: new Map(sorted.map((coreModule) => [coreModule.id, coreModule])),\n definitions: createModuleRegistryDefinitions(sorted),\n modules: Object.freeze(sorted),\n };\n}\n\nexport interface ModuleHostProps {\n boundary?: BoundaryComponent;\n children?: ReactNode;\n modules?: readonly AnyCoreModule[];\n registryEntries?: readonly AppRegistryEntry[];\n}\n\nexport function ModuleHost({\n boundary = PassthroughBoundary,\n children,\n modules = EMPTY_MODULES,\n registryEntries,\n}: ModuleHostProps) {\n const [host] = useState(() => createModuleHost(modules, boundary));\n const { Boundary } = host;\n\n const content = (\n <>\n {host.modules.map(({ Backdrop, id }) =>\n Backdrop ? (\n <Boundary key={id} name={id}>\n <Backdrop />\n </Boundary>\n ) : null,\n )}\n {children}\n {host.modules.map(({ Overlay, id }) =>\n Overlay ? (\n <Boundary key={id} name={id}>\n <Overlay />\n </Boundary>\n ) : null,\n )}\n </>\n );\n\n const tree = host.modules.reduceRight<ReactNode>(\n (inner, { Provider }) => (Provider ? <Provider>{inner}</Provider> : inner),\n content,\n );\n\n return (\n <RegistryProvider\n definitions={host.definitions}\n initialEntries={registryEntries}\n >\n <ModuleHostContext value={host}>\n <PageControllerProvider>{tree}</PageControllerProvider>\n </ModuleHostContext>\n </RegistryProvider>\n );\n}\n\nexport function useModule<K extends ModuleId>(\n id: K,\n): ModuleRuntimeOf<CoreModules[K]> | null {\n const coreModule = use(ModuleHostContext)?.byId.get(id);\n return coreModule?.context ? (use(coreModule.context) ?? null) : null;\n}\n\ntype ModuleActionsOf<K extends ModuleId> =\n ModuleRuntimeOf<CoreModules[K]> extends { actions: infer TActions }\n ? TActions\n : never;\n\nexport interface ModulePeer<K extends ModuleId> {\n useActions(): ModuleActionsOf<K>;\n useRuntime(): ModuleRuntimeOf<CoreModules[K]>;\n useState<T>(\n selector: (state: ModuleStateOf<K>) => T,\n isEqual?: (a: T, b: T) => boolean,\n ): T;\n}\n\nexport function definePeer<K extends ModuleId>(\n id: K,\n inert: ModuleRuntimeOf<CoreModules[K]>,\n): ModulePeer<K> {\n const useRuntime = (): ModuleRuntimeOf<CoreModules[K]> =>\n useModule(id) ?? inert;\n return {\n useRuntime,\n useActions: () => useRuntime().actions as ModuleActionsOf<K>,\n useState: <T,>(\n selector: (state: ModuleStateOf<K>) => T,\n isEqual?: (a: T, b: T) => boolean,\n ) =>\n useStore<ModuleStateOf<K>, T>(\n (useRuntime() as { store: ExternalStore<ModuleStateOf<K>> }).store,\n selector,\n isEqual,\n ),\n };\n}\n\nconst NO_MODULE_STORE: ExternalStore<unknown> = createStore<unknown>(undefined);\n\nexport function useModuleState<K extends ModuleId, T>(\n id: K,\n selector: (state: ModuleStateOf<K>) => T,\n fallback: T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n): T {\n const runtime = useModule(id) as { store: ExternalStore<unknown> } | null;\n return useStore<unknown, T>(\n runtime?.store ?? NO_MODULE_STORE,\n (state) => (runtime ? selector(state as ModuleStateOf<K>) : fallback),\n isEqual,\n );\n}\n\nexport function ModuleBoundary({\n children,\n name,\n}: {\n children?: ReactNode;\n name?: string;\n}) {\n const Boundary = use(ModuleHostContext)?.Boundary ?? PassthroughBoundary;\n return createElement(Boundary, { name }, children);\n}\n\nexport function useIsModuleInstalled(id: ModuleId): boolean {\n return use(ModuleHostContext)?.byId.has(id) ?? false;\n}\n","\"use client\";\n\nimport {\n createElement,\n useContext,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\nimport { getOrCreateGlobalContext } from \"@/kernel\";\n\nexport interface ThemeSpec<S extends string = string> {\n readonly id: string;\n readonly _slots?: S;\n}\n\nexport interface ThemeConfig<S extends string> {\n slots: Readonly<Record<S, string>>;\n styles?: Readonly<Partial<Record<S, CSSProperties>>>;\n}\n\nexport interface ResolvedTheme<S extends string> {\n readonly slots: Readonly<Record<S, string>>;\n readonly styles: Readonly<Partial<Record<S, CSSProperties>>>;\n}\n\nexport interface ThemeEntry {\n readonly id: string;\n readonly config: ThemeConfig<string>;\n}\n\nexport function defineThemeSpec<S extends string>(id: string): ThemeSpec<S> {\n return Object.freeze({ id });\n}\n\nexport function defineTheme<S extends string>(\n spec: ThemeSpec<S>,\n config: ThemeConfig<NoInfer<S>>,\n): ThemeEntry {\n return { id: spec.id, config: config as ThemeEntry[\"config\"] };\n}\n\nconst EMPTY: ReadonlyMap<string, ThemeEntry[\"config\"]> = new Map();\nconst ThemeContext = getOrCreateGlobalContext<\n ReadonlyMap<string, ThemeEntry[\"config\"]>\n>(\"ThemeContext\", EMPTY);\n\n\nexport function ThemeProvider({\n children,\n themes,\n}: {\n children?: ReactNode;\n themes: readonly ThemeEntry[];\n}) {\n const configs = new Map(themes.map((entry) => [entry.id, entry.config]));\n return createElement(ThemeContext.Provider, { value: configs }, children);\n}\n\nexport function useTheme<S extends string>(\n spec: ThemeSpec<S>,\n): ResolvedTheme<S> {\n const config = useContext(ThemeContext).get(spec.id);\n if (!config) {\n throw new Error(\n `Theme \"${spec.id}\" is missing. Ensure its theme configuration is provided to <ThemeProvider themes={[...]}> (e.g. in src/config/ or your theme setup).`,\n );\n }\n return {\n slots: config.slots,\n styles: config.styles ?? {},\n } as ResolvedTheme<S>;\n}\n\nexport { useTheme as useModuleTheme };\n\n","import { defineThemeSpec } from \"@/theme\";\nimport type { AmbientThemeSlot } from \"./types\";\n\nexport const AMBIENT_DEFAULTS = Object.freeze({\n primary: \"#101010\",\n black: \"#0b0b0b\",\n} as const);\n\nexport const ambientTheme = defineThemeSpec<AmbientThemeSlot>(\"ambient\");\n","import type { AmbientPalette, OklchColor } from \"./types\";\n\nexport const COLOR_EXTRACT_CONFIG = Object.freeze({\n blackChromaFactor: 0.35,\n primaryLightness: 0.74,\n maxBlackChroma: 0.055,\n blackLightness: 0.15,\n cacheLimit: 100,\n maxChroma: 0.28,\n minChroma: 0.03,\n sampleSize: 32,\n} as const);\n\nexport function srgbToLinear(c: number): number {\n const v = c / 255;\n return v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\n}\n\nexport function rgbToOklch(r: number, g: number, b: number): OklchColor {\n const lr = srgbToLinear(r);\n const lg = srgbToLinear(g);\n const lb = srgbToLinear(b);\n\n const l = 0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb;\n const m = 0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb;\n const s = 0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb;\n\n const l_ = Math.cbrt(l);\n const m_ = Math.cbrt(m);\n const s_ = Math.cbrt(s);\n\n const L = 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_;\n const a = 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_;\n const bOklab = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_;\n\n const C = Math.sqrt(a * a + bOklab * bOklab);\n const H = (Math.atan2(bOklab, a) * (180 / Math.PI) + 360) % 360;\n\n return {\n c: Math.max(0, Number(C.toFixed(3))),\n h: Math.max(0, Number(H.toFixed(1))),\n l: Math.max(0, Math.min(1, Number(L.toFixed(3)))),\n };\n}\n\nexport function oklchToString(\n l: number | string,\n c: number | string,\n h: number | string,\n alpha: number | string = 1,\n): string {\n const safeL = Math.max(0, Math.min(1, Number(l) || 0)).toFixed(3);\n const safeC = Math.max(0, Number(c) || 0).toFixed(3);\n const safeH = (Number(h) || 0).toFixed(1);\n const numericAlpha = Number(alpha);\n if (Number.isFinite(numericAlpha) && numericAlpha < 1 && numericAlpha >= 0) {\n return `oklch(${safeL} ${safeC} ${safeH} / ${numericAlpha})`;\n }\n return `oklch(${safeL} ${safeC} ${safeH})`;\n}\n\nexport function derivePalette(sampled: OklchColor): AmbientPalette {\n const {\n blackChromaFactor,\n blackLightness,\n maxBlackChroma,\n maxChroma,\n minChroma,\n primaryLightness,\n } = COLOR_EXTRACT_CONFIG;\n const chroma = Math.max(minChroma, Math.min(maxChroma, sampled.c));\n const blackChroma = Math.min(\n maxBlackChroma,\n Math.max(0.025, chroma * blackChromaFactor),\n );\n const primaryChroma = Math.max(\n 0.15,\n Math.min(0.24, Math.max(chroma * 1.15, 0.18)),\n );\n\n return {\n black: oklchToString(blackLightness, blackChroma, sampled.h),\n primary: oklchToString(primaryLightness, primaryChroma, sampled.h),\n };\n}\n","import { COLOR_EXTRACT_CONFIG, derivePalette, rgbToOklch } from \"./color\";\nimport { AMBIENT_DEFAULTS } from \"./constants\";\nimport type {\n AmbientExtractOptions,\n AmbientImageSource,\n AmbientPalette,\n OklchColor,\n} from \"./types\";\n\nexport function sampleImageData(imageData: ImageData): OklchColor {\n const data = imageData.data;\n const len = data.length;\n const numBins = 24;\n const binAngle = 360 / numBins;\n\n const bins = Array.from({ length: numBins }, () => ({\n count: 0,\n sumC: 0,\n sumCos: 0,\n sumL: 0,\n sumSin: 0,\n }));\n\n let neutralCount = 0;\n let neutralSumL = 0;\n let chromaticCount = 0;\n\n for (let i = 0; i < len; i += 4) {\n const alpha = data[i + 3];\n if (alpha < 128) continue;\n\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n\n const oklch = rgbToOklch(r, g, b);\n\n if (oklch.l < 0.04 || oklch.l > 0.96 || oklch.c < 0.02) {\n neutralCount++;\n neutralSumL += oklch.l;\n continue;\n }\n\n const binIndex = Math.floor(oklch.h / binAngle) % numBins;\n const rad = oklch.h * (Math.PI / 180);\n\n const bin = bins[binIndex];\n bin.count++;\n bin.sumL += oklch.l;\n bin.sumC += oklch.c;\n bin.sumCos += Math.cos(rad);\n bin.sumSin += Math.sin(rad);\n chromaticCount++;\n }\n\n if (chromaticCount === 0) {\n const avgL = neutralCount > 0 ? neutralSumL / neutralCount : 0.55;\n return { c: 0.03, h: 252, l: avgL };\n }\n\n let bestIndex = 0;\n let maxWindowCount = -1;\n\n for (let i = 0; i < numBins; i++) {\n const prev = bins[(i - 1 + numBins) % numBins];\n const curr = bins[i];\n const next = bins[(i + 1) % numBins];\n const windowCount = prev.count * 0.5 + curr.count + next.count * 0.5;\n\n if (windowCount > maxWindowCount) {\n maxWindowCount = windowCount;\n bestIndex = i;\n }\n }\n\n const prev = bins[(bestIndex - 1 + numBins) % numBins];\n const curr = bins[bestIndex];\n const next = bins[(bestIndex + 1) % numBins];\n\n const totalCount = prev.count + curr.count + next.count;\n if (totalCount === 0) {\n return { c: 0.19, h: 252, l: 0.55 };\n }\n\n const avgL = (prev.sumL + curr.sumL + next.sumL) / totalCount;\n const avgC = (prev.sumC + curr.sumC + next.sumC) / totalCount;\n const avgSin = prev.sumSin + curr.sumSin + next.sumSin;\n const avgCos = prev.sumCos + curr.sumCos + next.sumCos;\n const avgH = (Math.atan2(avgSin, avgCos) * (180 / Math.PI) + 360) % 360;\n\n return {\n c: Number(avgC.toFixed(3)),\n h: Number(avgH.toFixed(1)),\n l: Number(avgL.toFixed(3)),\n };\n}\n\nexport function createDefaultPalette(\n fallback?: AmbientPalette | null,\n): AmbientPalette {\n return {\n black: fallback?.black || AMBIENT_DEFAULTS.black,\n primary: fallback?.primary || AMBIENT_DEFAULTS.primary,\n };\n}\n\nconst paletteCache = new Map<string, AmbientPalette>();\nconst inFlight = new Map<string, Promise<AmbientPalette | null>>();\n\nasync function fetchObjectUrl(src: string): Promise<string | null> {\n if (typeof fetch !== \"function\" || !src.startsWith(\"http\")) return null;\n\n const corsUrl = src.includes(\"cors=\")\n ? src\n : `${src}${src.includes(\"?\") ? \"&\" : \"?\"}cors=1`;\n const attempts: [string, RequestInit?][] = [\n [corsUrl, { mode: \"cors\" }],\n [`/api/ambient/proxy?url=${encodeURIComponent(src)}`],\n ];\n\n for (const [url, init] of attempts) {\n try {\n const response = await fetch(url, init);\n if (response.ok) return URL.createObjectURL(await response.blob());\n } catch {}\n }\n return null;\n}\n\nfunction loadImage(\n url: string,\n crossOrigin: boolean,\n): Promise<HTMLImageElement | null> {\n return new Promise((resolve) => {\n const image = new Image();\n if (crossOrigin) image.crossOrigin = \"anonymous\";\n image.onload = () => resolve(image);\n image.onerror = () => resolve(null);\n image.src = url;\n });\n}\n\nfunction readPalette(image: HTMLImageElement): AmbientPalette | null {\n const size = COLOR_EXTRACT_CONFIG.sampleSize;\n const canvas = document.createElement(\"canvas\");\n canvas.width = size;\n canvas.height = size;\n const context = canvas.getContext(\"2d\", { willReadFrequently: true });\n if (!context) return null;\n\n context.drawImage(image, 0, 0, size, size);\n return derivePalette(sampleImageData(context.getImageData(0, 0, size, size)));\n}\n\nasync function extractPalette(src: string): Promise<AmbientPalette | null> {\n const objectUrl = await fetchObjectUrl(src);\n try {\n const image = await loadImage(objectUrl ?? src, !objectUrl);\n return image ? readPalette(image) : null;\n } catch {\n return null;\n } finally {\n if (objectUrl) URL.revokeObjectURL(objectUrl);\n }\n}\n\nfunction cachePalette(src: string, palette: AmbientPalette): void {\n if (paletteCache.size >= COLOR_EXTRACT_CONFIG.cacheLimit) {\n const oldest = paletteCache.keys().next().value;\n if (oldest) paletteCache.delete(oldest);\n }\n paletteCache.set(src, palette);\n}\n\nexport async function extractPaletteFromImage(\n imageSource: AmbientImageSource,\n options: AmbientExtractOptions = {},\n): Promise<AmbientPalette> {\n const fallback = createDefaultPalette(\n options.initialPalette || options.fallbackPalette,\n );\n const src = typeof imageSource === \"string\" ? imageSource : imageSource?.src;\n if (!src || typeof window === \"undefined\") return fallback;\n\n const cached = paletteCache.get(src);\n if (cached) return cached;\n\n let pending = inFlight.get(src);\n if (!pending) {\n pending = extractPalette(src)\n .then((palette) => {\n if (palette) cachePalette(src, palette);\n return palette;\n })\n .finally(() => inFlight.delete(src));\n inFlight.set(src, pending);\n }\n return (await pending) ?? fallback;\n}\n","import type { AmbientImageSource, AmbientTarget } from \"./types\";\n\nexport const AMBIENT_CSS_VARS = Object.freeze({\n ambientGlow: \"--color-ambient-glow\",\n colorPrimary: \"--color-primary\",\n primary: \"--primary\",\n black: \"--black\",\n white: \"--white\",\n} as const);\n\nexport function resolveTargetElement(\n target: AmbientTarget,\n): HTMLElement | null {\n if (typeof document === \"undefined\") return null;\n if (!target) return document.documentElement;\n if (typeof target === \"string\") {\n return document.querySelector<HTMLElement>(target);\n }\n return \"current\" in target ? target.current : target;\n}\n\nexport function normalizeColorMap(\n colors: Record<string, string>,\n): Record<string, string> {\n const cssVars = AMBIENT_CSS_VARS as Record<string, string>;\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(colors)) {\n if (!value) continue;\n const name =\n cssVars[key] ||\n (key.startsWith(\"--\")\n ? key\n : cssVars[key.toLowerCase()] || `--color-${key}`);\n result[name] = value;\n }\n return result;\n}\n\nexport function applyScopedCssVariables(\n element: HTMLElement,\n varMap: Record<string, string>,\n): () => void {\n const previous = new Map<string, { priority: string; value: string }>();\n for (const [name, value] of Object.entries(varMap)) {\n if (!name || !value) continue;\n previous.set(name, {\n priority: element.style.getPropertyPriority(name),\n value: element.style.getPropertyValue(name),\n });\n element.style.setProperty(name, value);\n }\n\n return () => {\n for (const [name, { priority, value }] of previous) {\n if (value) element.style.setProperty(name, value, priority);\n else element.style.removeProperty(name);\n }\n };\n}\n\nexport function resolveAmbientVarMap({\n colors = null,\n extractedBlack = \"\",\n extractedPrimary = \"\",\n image = null,\n tintGlobals = true,\n}: {\n colors?: Record<string, string> | null;\n extractedBlack?: string;\n extractedPrimary?: string;\n image?: AmbientImageSource;\n tintGlobals?: boolean;\n}): Record<string, string> {\n const varMap: Record<string, string> = {};\n\n if (image) {\n if (extractedPrimary) {\n varMap[AMBIENT_CSS_VARS.primary] = extractedPrimary;\n varMap[AMBIENT_CSS_VARS.ambientGlow] = extractedPrimary;\n if (tintGlobals) varMap[AMBIENT_CSS_VARS.colorPrimary] = extractedPrimary;\n }\n if (extractedBlack) varMap[AMBIENT_CSS_VARS.black] = extractedBlack;\n }\n\n if (colors) Object.assign(varMap, normalizeColorMap(colors));\n\n return varMap;\n}\n","import {\n type BackgroundActions,\n type BackgroundState,\n type BackgroundStateComputed,\n type ScopedOverride,\n} from \"./types\";\nimport {\n extractYouTubeVideoId,\n getYouTubeThumbnailUrl,\n isDirectVideoUrl,\n isYouTubeUrl,\n} from \"./youtube/parse\";\n\nexport const DEFAULT_BACKGROUND: BackgroundState = Object.freeze({\n animation: null,\n className: \"\",\n fadeEdges: null,\n fit: null,\n image: null,\n imageStyle: {},\n isPlaying: false,\n noiseStyle: {},\n overlay: false,\n overlayColor: \"var(--black)\",\n overlayOpacity: 0,\n position: \"center\",\n video: null,\n videoClassName: \"\",\n videoElement: null,\n videoOptions: {\n autoplay: true,\n className: \"\",\n corp: 0,\n loop: false,\n muted: true,\n playbackRate: 1,\n width: null,\n },\n videoStyle: {},\n width: null,\n});\n\nexport const DEFAULT_BACKGROUND_COMPUTED: BackgroundStateComputed = Object.freeze({\n ...DEFAULT_BACKGROUND,\n hasBackground: false,\n isVideo: false,\n isYouTube: false,\n posterUrl: null,\n youtubeVideoId: null,\n});\n\nexport const INERT_BACKGROUND_ACTIONS: BackgroundActions = Object.freeze({\n resetBackground: () => {},\n setBackground: () => {},\n setVideoElement: () => {},\n setVideoMuted: () => {},\n setVideoPlaying: () => {},\n toggleLoop: () => {},\n toggleMute: () => {},\n toggleVideo: () => {},\n});\n\nexport function normalizeBackgroundInput(\n patch: Partial<BackgroundState> | string | null | undefined = {},\n): Partial<BackgroundState> {\n if (!patch) return {};\n\n if (typeof patch === \"string\") {\n const trimmed = patch.trim();\n if (isYouTubeUrl(trimmed) || isDirectVideoUrl(trimmed)) {\n return { image: null, video: trimmed };\n }\n return { image: trimmed };\n }\n\n const nextPatch: Partial<BackgroundState> = { ...patch };\n\n if (\n typeof nextPatch.image === \"string\" &&\n isYouTubeUrl(nextPatch.image) &&\n !nextPatch.video\n ) {\n nextPatch.video = nextPatch.image;\n nextPatch.image = null;\n }\n\n return nextPatch;\n}\n\nexport function mergeBackgroundState(\n baseState: BackgroundState,\n patch: Partial<BackgroundState> | string = {},\n): BackgroundState {\n const resolvedPatch = normalizeBackgroundInput(patch);\n\n const nextVideoOptions = {\n ...baseState.videoOptions,\n ...(resolvedPatch.videoOptions || {}),\n };\n\n const nextVideo =\n resolvedPatch.video !== undefined ? resolvedPatch.video : baseState.video;\n const shouldAutoPlay = nextVideoOptions.autoplay !== false;\n const resolvedIsPlaying =\n resolvedPatch.isPlaying !== undefined\n ? resolvedPatch.isPlaying\n : resolvedPatch.video !== undefined && Boolean(nextVideo)\n ? shouldAutoPlay\n : baseState.isPlaying;\n\n return {\n ...baseState,\n ...resolvedPatch,\n isPlaying: resolvedIsPlaying,\n animation:\n resolvedPatch.animation !== undefined\n ? resolvedPatch.animation\n ? {\n ...(baseState.animation || {}),\n ...resolvedPatch.animation,\n }\n : resolvedPatch.animation\n : baseState.animation,\n imageStyle: {\n ...baseState.imageStyle,\n ...(resolvedPatch.imageStyle || {}),\n },\n noiseStyle: {\n ...baseState.noiseStyle,\n ...(resolvedPatch.noiseStyle || {}),\n },\n videoOptions: nextVideoOptions,\n videoStyle: {\n ...baseState.videoStyle,\n ...(resolvedPatch.videoStyle || {}),\n },\n };\n}\n\nexport function resolveBackgroundState(\n registryBackground: Partial<BackgroundState> | null,\n override: ScopedOverride,\n pathname: string | null,\n): BackgroundState {\n const base = registryBackground\n ? mergeBackgroundState(DEFAULT_BACKGROUND, registryBackground)\n : DEFAULT_BACKGROUND;\n const patch = override.pathname === pathname ? override.patch : null;\n return patch ? mergeBackgroundState(base, patch) : base;\n}\n\nexport function computeBackgroundState(\n background: BackgroundState,\n): BackgroundStateComputed {\n const youtubeVideoId = extractYouTubeVideoId(background.video);\n const isYouTube = Boolean(youtubeVideoId);\n const isVideo = Boolean(background.video || isYouTube);\n\n return {\n ...background,\n hasBackground: Boolean(\n background.image ||\n isVideo ||\n background.color ||\n background.overlay ||\n (background.noiseStyle &&\n (background.noiseStyle.opacity === undefined ||\n (background.noiseStyle.opacity ?? 0) > 0)),\n ),\n isVideo,\n isYouTube,\n posterUrl: youtubeVideoId ? getYouTubeThumbnailUrl(youtubeVideoId) : null,\n youtubeVideoId,\n };\n}\n","\"use client\";\n\nimport {\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { usePathname } from \"next/navigation\";\nimport {\n useIsomorphicLayoutEffect,\n useStore,\n} from \"@/hooks\";\nimport {\n getOrCreateGlobalContext,\n useRegistryValue,\n} from \"@/kernel\";\nimport { useOptionalMediaActions } from \"../media\";\nimport { createStore } from \"@/utils\";\nimport {\n BACKGROUND_MEDIA_ID,\n BACKGROUND_REGISTRY_KEY,\n} from \"./constants\";\nimport {\n computeBackgroundState,\n normalizeBackgroundInput,\n resolveBackgroundState,\n} from \"./state\";\nimport {\n syncVideoLoopDirect,\n syncVideoMutedDirect,\n triggerVideoPlaybackDirect,\n} from \"./playback\";\nimport {\n type BackgroundActions,\n type BackgroundContextValue,\n type BackgroundProviderProps,\n type BackgroundState,\n type BackgroundStateComputed,\n type ScopedOverride,\n} from \"./types\";\n\nexport const BackgroundContext =\n getOrCreateGlobalContext<BackgroundContextValue | null>(\n \"BackgroundContext\",\n null,\n );\n\nfunction useSafePathname(): string | null {\n try {\n return usePathname();\n } catch {\n return null;\n }\n}\n\nexport function BackgroundProvider({ children }: BackgroundProviderProps) {\n const pathname = useSafePathname();\n const registryBackground =\n useRegistryValue<\"background\", Partial<BackgroundState>>(\n \"background\",\n BACKGROUND_REGISTRY_KEY,\n ) ?? null;\n\n const [overrideStore] = useState(() =>\n createStore<ScopedOverride>(\n { patch: null, pathname },\n { freezeSnapshots: false },\n ),\n );\n const scopedOverride = useStore(overrideStore);\n\n const inputsRef = useRef({ pathname, registryBackground });\n useIsomorphicLayoutEffect(() => {\n inputsRef.current = { pathname, registryBackground };\n }, [pathname, registryBackground]);\n\n const videoElementRef = useRef<HTMLVideoElement | null>(null);\n\n const state = useMemo(\n () =>\n computeBackgroundState(\n resolveBackgroundState(registryBackground, scopedOverride, pathname),\n ),\n [pathname, registryBackground, scopedOverride],\n );\n\n const [stateStore] = useState(() =>\n createStore<BackgroundStateComputed>(state, { freezeSnapshots: false }),\n );\n useIsomorphicLayoutEffect(() => {\n stateStore.publish(state);\n }, [state, stateStore]);\n\n const actions = useMemo<BackgroundActions>(() => {\n const readCurrent = (): BackgroundState => {\n const { pathname: currentPath, registryBackground: registry } =\n inputsRef.current;\n return resolveBackgroundState(\n registry,\n overrideStore.getSnapshot(),\n currentPath,\n );\n };\n\n const updatePatch = (\n updater: (current: BackgroundState) => Partial<BackgroundState>,\n ) => {\n overrideStore.publish((prev) => {\n const { pathname: currentPath, registryBackground: registry } =\n inputsRef.current;\n const currentPatch = prev.pathname === currentPath ? prev.patch : null;\n const rawNext = updater(\n resolveBackgroundState(registry, prev, currentPath),\n );\n if (!rawNext || Object.keys(rawNext).length === 0) {\n return prev;\n }\n const normalizedNext = normalizeBackgroundInput(rawNext);\n const mergedPatch: Partial<BackgroundState> = {\n ...(currentPatch || {}),\n ...normalizedNext,\n ...(currentPatch?.videoOptions || normalizedNext.videoOptions\n ? {\n videoOptions: {\n ...(currentPatch?.videoOptions || {}),\n ...(normalizedNext.videoOptions || {}),\n },\n }\n : {}),\n };\n return {\n patch: mergedPatch,\n pathname: currentPath,\n };\n });\n };\n\n const currentVideoElement = (current: BackgroundState) =>\n videoElementRef.current || current.videoElement;\n\n return {\n resetBackground: () => {\n overrideStore.publish({\n patch: null,\n pathname: inputsRef.current.pathname,\n });\n },\n setBackground: (nextBackground: Partial<BackgroundState> | string) => {\n updatePatch(() => normalizeBackgroundInput(nextBackground));\n },\n setVideoElement: (videoElement: HTMLVideoElement | null) => {\n videoElementRef.current = videoElement;\n updatePatch((cur) =>\n cur.videoElement === videoElement ? {} : { videoElement },\n );\n },\n setVideoMuted: (muted: boolean) => {\n const nextMuted = Boolean(muted);\n syncVideoMutedDirect(currentVideoElement(readCurrent()), nextMuted);\n updatePatch((cur) => {\n if (cur.videoOptions?.muted === nextMuted) return {};\n return {\n videoOptions: { ...cur.videoOptions, muted: nextMuted },\n };\n });\n },\n setVideoPlaying: (isPlaying: boolean) => {\n updatePatch((cur) =>\n cur.isPlaying === isPlaying ? {} : { isPlaying },\n );\n },\n toggleLoop: () => {\n const current = readCurrent();\n const nextLoop = !current.videoOptions?.loop;\n syncVideoLoopDirect(currentVideoElement(current), nextLoop);\n updatePatch((cur) => ({\n videoOptions: { ...cur.videoOptions, loop: nextLoop },\n }));\n },\n toggleMute: () => {\n const current = readCurrent();\n const nextMuted = !current.videoOptions?.muted;\n syncVideoMutedDirect(currentVideoElement(current), nextMuted);\n updatePatch((cur) => ({\n isPlaying: nextMuted ? cur.isPlaying : true,\n videoOptions: { ...cur.videoOptions, muted: nextMuted },\n }));\n },\n toggleVideo: () => {\n const current = readCurrent();\n const videoEl = currentVideoElement(current);\n const domIsActuallyPlaying = videoEl\n ? !videoEl.paused && !videoEl.ended\n : Boolean(current.isPlaying);\n const nextPlaying = !domIsActuallyPlaying;\n const configuredMuted = Boolean(current.videoOptions?.muted);\n\n triggerVideoPlaybackDirect(videoEl, nextPlaying, configuredMuted);\n\n updatePatch(() => ({ isPlaying: nextPlaying }));\n },\n };\n }, [overrideStore]);\n\n const media = useOptionalMediaActions();\n const { isPlaying, isVideo, videoElement } = state;\n const isLoop = Boolean(state.videoOptions?.loop);\n useEffect(() => {\n if (!isVideo) {\n media.removeSource(BACKGROUND_MEDIA_ID);\n return;\n }\n media.upsertSource({\n controls: {\n setMuted: actions.setVideoMuted,\n toggle: actions.toggleVideo,\n toggleLoop: actions.toggleLoop,\n },\n element: videoElement ?? null,\n id: BACKGROUND_MEDIA_ID,\n isPlaying,\n kind: \"video\",\n loop: isLoop,\n });\n }, [actions, isLoop, isPlaying, isVideo, media, videoElement]);\n useEffect(() => () => media.removeSource(BACKGROUND_MEDIA_ID), [media]);\n\n const value = useMemo<BackgroundContextValue>(\n () => ({ actions, store: stateStore }),\n [actions, stateStore],\n );\n\n return <BackgroundContext value={value}>{children}</BackgroundContext>;\n}\n","\"use client\";\n\nimport { useContext, useMemo } from \"react\";\nimport { useRequiredContext, useStore } from \"@/hooks\";\nimport {\n useModuleRegistration,\n type RegistryMetadata,\n} from \"@/kernel\";\nimport { createStore } from \"@/utils\";\nimport { BackgroundContext } from \"./context\";\nimport {\n DEFAULT_BACKGROUND_COMPUTED,\n INERT_BACKGROUND_ACTIONS,\n} from \"./state\";\nimport type {\n BackgroundActions,\n BackgroundPageConfig,\n BackgroundStateComputed,\n} from \"./types\";\n\nconst NOOP_BACKGROUND_STORE = createStore<BackgroundStateComputed>(\n DEFAULT_BACKGROUND_COMPUTED,\n);\n\nexport function useBackgroundRegistration(\n config: BackgroundPageConfig | null | undefined,\n options?: RegistryMetadata & { enabled?: boolean },\n): void {\n useModuleRegistration(\"background\", config, options);\n}\n\nexport function useBackgroundState(): BackgroundStateComputed {\n const { store } = useRequiredContext(\n BackgroundContext,\n \"useBackgroundState\",\n \"BackgroundProvider\",\n );\n return useStore(store);\n}\n\nexport function useBackgroundActions(): BackgroundActions {\n return useRequiredContext(\n BackgroundContext,\n \"useBackgroundActions\",\n \"BackgroundProvider\",\n ).actions;\n}\n\nexport function useBackground(\n config?: BackgroundPageConfig | null,\n options?: RegistryMetadata & { enabled?: boolean },\n): BackgroundStateComputed & BackgroundActions {\n useBackgroundRegistration(config, options);\n\n const actions = useBackgroundActions();\n const state = useBackgroundState();\n\n return useMemo(() => ({ ...state, ...actions }), [actions, state]);\n}\n\nexport function useOptionalBackgroundState(): BackgroundStateComputed;\nexport function useOptionalBackgroundState<T>(\n selector: (state: BackgroundStateComputed) => T,\n isEqual?: (a: T, b: T) => boolean,\n): T;\nexport function useOptionalBackgroundState<T = BackgroundStateComputed>(\n selector?: (state: BackgroundStateComputed) => T,\n isEqual?: (a: T, b: T) => boolean,\n): T {\n const ctx = useContext(BackgroundContext);\n return useStore(\n ctx?.store ?? NOOP_BACKGROUND_STORE,\n selector as (state: BackgroundStateComputed) => T,\n isEqual,\n );\n}\n\nexport function useOptionalBackgroundActions(): BackgroundActions {\n const ctx = useContext(BackgroundContext);\n return ctx?.actions ?? INERT_BACKGROUND_ACTIONS;\n}\n","\"use client\";\n\nimport { useMemo, useState } from \"react\";\nimport { createStore } from \"@/utils\";\nimport { getOrCreateGlobalContext } from \"@/kernel\";\nimport { AMBIENT_DEFAULTS } from \"./constants\";\nimport type {\n AmbientProviderProps,\n AmbientProviderValue,\n AmbientState,\n} from \"./types\";\n\nexport const AmbientContext =\n getOrCreateGlobalContext<AmbientProviderValue | null>(\"AmbientContext\", null);\n\nexport function AmbientProvider({\n children,\n initialPalette = null,\n}: AmbientProviderProps) {\n const [store] = useState(() =>\n createStore<AmbientState>(\n { isExtracting: false, palette: initialPalette || AMBIENT_DEFAULTS },\n { freezeSnapshots: false },\n ),\n );\n\n const value = useMemo<AmbientProviderValue>(\n () => ({\n actions: {\n setIsExtracting: (next) =>\n store.publish((state) => {\n const isExtracting =\n typeof next === \"function\" ? next(state.isExtracting) : next;\n return isExtracting === state.isExtracting\n ? state\n : { ...state, isExtracting };\n }),\n setPalette: (next) =>\n store.publish((state) => {\n const palette =\n typeof next === \"function\" ? next(state.palette) : next;\n return palette === state.palette ? state : { ...state, palette };\n }),\n },\n store,\n }),\n [store],\n );\n\n return <AmbientContext value={value}>{children}</AmbientContext>;\n}\n","\"use client\";\n\nimport { use, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useRequiredContext, useStore } from \"@/hooks\";\nimport { shallowEqual } from \"@/utils\";\nimport { useModuleTheme } from \"@/theme\";\nimport { AMBIENT_DEFAULTS, ambientTheme } from \"./constants\";\nimport { AmbientContext } from \"./context\";\nimport { extractPaletteFromImage } from \"./extractor\";\nimport {\n applyScopedCssVariables,\n resolveAmbientVarMap,\n resolveTargetElement,\n} from \"./dom\";\nimport type {\n AmbientConfig,\n AmbientContextValue,\n AmbientExtractOptions,\n AmbientImageSource,\n AmbientPalette,\n AmbientState,\n} from \"./types\";\n\nexport function useStableObject<T extends object | null | undefined>(value: T): T {\n const ref = useRef<T>(value);\n if (!shallowEqual(ref.current, value)) {\n ref.current = value;\n }\n return ref.current;\n}\n\nexport function useAmbientColor(\n imageSource: AmbientImageSource,\n options: AmbientExtractOptions | null = null,\n): { isExtracting: boolean; palette: AmbientPalette } {\n const stableOptions = useStableObject(options);\n const initialPalette = useStableObject(\n options?.initialPalette || options?.fallbackPalette || null,\n );\n\n const [extractedData, setExtractedData] = useState<AmbientPalette | null>(\n () => initialPalette,\n );\n\n const srcKey =\n typeof imageSource === \"string\" ? imageSource : imageSource?.src;\n\n const isExtracting = Boolean(\n imageSource && (!extractedData || extractedData.source !== srcKey),\n );\n\n useEffect(() => {\n if (!imageSource) return;\n\n let active = true;\n\n void extractPaletteFromImage(imageSource, {\n fallbackPalette: initialPalette,\n ...(stableOptions || {}),\n })\n .then((extracted) => {\n if (active) {\n setExtractedData({ ...extracted, source: srcKey });\n }\n })\n .catch(() => {\n if (active) {\n setExtractedData({\n black: initialPalette?.black || AMBIENT_DEFAULTS.black,\n primary: initialPalette?.primary || AMBIENT_DEFAULTS.primary,\n source: srcKey,\n });\n }\n });\n\n return () => {\n active = false;\n };\n }, [imageSource, initialPalette, srcKey, stableOptions]);\n\n const palette =\n imageSource && extractedData && extractedData.source === srcKey\n ? extractedData\n : initialPalette || AMBIENT_DEFAULTS;\n\n return { isExtracting, palette };\n}\n\nexport function useAmbientTheme(\n config: AmbientConfig | string | null = null,\n): AmbientState {\n const ambientActions = use(AmbientContext)?.actions ?? null;\n const normalizedConfig: AmbientConfig =\n typeof config === \"string\" ? { image: config } : config || {};\n\n const {\n colors = null,\n image = null,\n initialPalette = null,\n options = null,\n scope = null,\n tintGlobals = true,\n transition = true,\n } = normalizedConfig;\n\n const stableInitialPalette = useStableObject(initialPalette);\n const stableOptions = useStableObject(options);\n const stableColors = useStableObject(colors);\n\n const resolvedOptions = useMemo<AmbientExtractOptions>(\n () => ({\n ...(stableOptions || {}),\n ...(stableInitialPalette ? { initialPalette: stableInitialPalette } : {}),\n }),\n [stableInitialPalette, stableOptions],\n );\n\n const { palette: extractedPalette, isExtracting } = useAmbientColor(\n image,\n resolvedOptions,\n );\n\n const hasActiveConfig = Boolean(image || stableColors);\n\n useEffect(() => {\n if (!hasActiveConfig || !ambientActions) return;\n ambientActions.setIsExtracting(isExtracting);\n ambientActions.setPalette((prev) =>\n shallowEqual(prev, extractedPalette) ? prev : extractedPalette,\n );\n }, [ambientActions, extractedPalette, hasActiveConfig, isExtracting]);\n\n const extractedPrimary = extractedPalette?.primary || \"\";\n const extractedBlack = extractedPalette?.black || \"\";\n\n const transitionClasses = useModuleTheme(ambientTheme)\n .slots.transition.split(/\\s+/)\n .filter(Boolean);\n const transitionKey = transitionClasses.join(\" \");\n\n const resolvedVarMap = useMemo(\n () =>\n resolveAmbientVarMap({\n colors: stableColors,\n extractedBlack,\n extractedPrimary,\n image,\n tintGlobals,\n }),\n [extractedBlack, extractedPrimary, image, stableColors, tintGlobals],\n );\n\n useEffect(() => {\n if (Object.keys(resolvedVarMap).length === 0) return;\n\n const targetEl = resolveTargetElement(scope);\n if (!targetEl) return;\n\n if (transition) {\n targetEl.classList.add(...transitionKey.split(\" \").filter(Boolean));\n }\n\n const restoreVariables = applyScopedCssVariables(targetEl, resolvedVarMap);\n\n return () => {\n restoreVariables();\n if (transition && scope) {\n targetEl.classList.remove(...transitionKey.split(\" \").filter(Boolean));\n }\n };\n }, [resolvedVarMap, scope, transition, transitionKey]);\n\n return { isExtracting, palette: extractedPalette };\n}\n\nexport function useAmbient(\n configOrImage?: AmbientConfig | string | null,\n): AmbientContextValue {\n const { actions, store } = useRequiredContext(\n AmbientContext,\n \"useAmbient\",\n \"AmbientProvider\",\n );\n const shared = useStore(store);\n const ctx = useMemo<AmbientContextValue>(\n () => ({ ...shared, ...actions }),\n [actions, shared],\n );\n const { isExtracting, palette } = useAmbientTheme(configOrImage ?? null);\n const themeState = useMemo(\n () => ({ isExtracting, palette }),\n [isExtracting, palette],\n );\n\n return useMemo(\n () => (configOrImage ? { ...ctx, ...themeState } : ctx),\n [configOrImage, ctx, themeState],\n );\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport {\n defineModule,\n type PageConfig,\n type PageModuleApi,\n} from \"@/kernel\";\nimport { useOptionalBackgroundState } from \"../background\";\nimport { AmbientContext, AmbientProvider } from \"./context\";\nimport { useAmbientTheme } from \"./hooks\";\nimport type {\n AmbientConfig,\n AmbientDescriptor,\n AmbientOverrides,\n AmbientPageApi,\n AmbientPageConfig,\n AmbientPageSlice,\n DefineAmbientOptions,\n DefinedAmbient,\n} from \"./types\";\n\nconst firstString = (...values: unknown[]): string | null =>\n (values.find((value) => typeof value === \"string\" && value) as string) ??\n null;\n\nexport function resolvePageAmbientTheme(\n slice: AmbientPageSlice | null,\n posterUrl: string | null,\n): Partial<AmbientConfig> | null {\n const ambient = slice?.ambient;\n const banner = slice?.banner ?? null;\n const defaultImage = banner ?? posterUrl;\n\n if (ambient === false) return null;\n if (ambient === true || typeof ambient === \"string\") {\n return {\n image: typeof ambient === \"string\" ? ambient : defaultImage,\n tintGlobals: true,\n };\n }\n if (ambient && typeof ambient === \"object\") {\n return { image: ambient.image ?? defaultImage, ...ambient };\n }\n if (banner && !posterUrl) return { image: banner, tintGlobals: true };\n return null;\n}\n\nexport function selectPageAmbient(config: PageConfig): AmbientPageSlice {\n return {\n ambient: config.ambient,\n banner: firstString(config.dock?.banner, config.dock?.bannerUrl),\n };\n}\n\nexport function useAmbientPage(\n slice: AmbientPageSlice | null,\n page: PageModuleApi,\n): AmbientPageApi {\n const posterUrl = useOptionalBackgroundState(\n (background) => background.posterUrl,\n );\n const theme = useMemo(\n () => resolvePageAmbientTheme(slice, posterUrl),\n [posterUrl, slice],\n );\n useAmbientTheme(theme);\n return useMemo(\n () => ({ set: (ambient: AmbientPageConfig) => page.set({ ambient }) }),\n [page],\n );\n}\n\nexport const ambientModule = defineModule({\n id: \"ambient\",\n context: AmbientContext,\n Provider: AmbientProvider,\n uses: [\"background\"],\n page: {\n select: selectPageAmbient,\n use: useAmbientPage,\n },\n});\n\ndeclare module \"@omerdlw/base-framework/kernel\" {\n interface CoreModules {\n ambient: typeof ambientModule;\n }\n interface PageConfig {\n ambient?: AmbientPageConfig;\n }\n}\n\nfunction resolveValue<T, P>(value: T | ((props: P) => T), props: P): T {\n return typeof value === \"function\"\n ? (value as (props: P) => T)(props)\n : value;\n}\n\nexport function defineAmbient(\n definition: DefineAmbientOptions = {},\n): DefinedAmbient {\n const { defaultProps, id = \"ambient-theme\", ...config } = definition;\n\n const create = (\n props: Record<string, unknown> = {},\n { id: overrideId, ...overrides }: AmbientOverrides = {},\n ): AmbientDescriptor => {\n const mergedProps = { ...defaultProps, ...props };\n const merged = { ...config, ...overrides };\n\n return {\n ...merged,\n colors: resolveValue(merged.colors ?? null, mergedProps) ?? null,\n id: overrideId ?? id,\n image: resolveValue(merged.image ?? null, mergedProps),\n initialPalette: merged.initialPalette ?? null,\n options: { ...config.options, ...overrides.options },\n props: mergedProps,\n scope: merged.scope ?? null,\n transition: merged.transition ?? true,\n };\n };\n\n return Object.freeze({\n config: definition,\n create,\n id,\n use: function useDefinedAmbient(\n props?: Record<string, unknown>,\n overrides?: AmbientOverrides,\n ) {\n return useAmbientTheme(create(props, overrides));\n },\n });\n}\n"]}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -1,4 +1,4 @@
1
- import { type PageConfig, type PageModuleApi } from "@/kernel";
1
+ import { type PageConfig, type PageModuleApi } from "../../kernel";
2
2
  import type { AmbientConfig, AmbientPageApi, AmbientPageConfig, AmbientPageSlice, DefineAmbientOptions, DefinedAmbient } from "./types";
3
3
  export declare function resolvePageAmbientTheme(slice: AmbientPageSlice | null, posterUrl: string | null): Partial<AmbientConfig> | null;
4
4
  export declare function selectPageAmbient(config: PageConfig): AmbientPageSlice;
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../src/modules/ambient/module.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,aAAa,EACnB,MAAM,UAAU,CAAC;AAIlB,OAAO,KAAK,EACV,aAAa,EAGb,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACf,MAAM,SAAS,CAAC;AAMjB,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,gBAAgB,GAAG,IAAI,EAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,GACvB,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAiB/B;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,gBAAgB,CAKtE;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,gBAAgB,GAAG,IAAI,EAC9B,IAAI,EAAE,aAAa,GAClB,cAAc,CAahB;AAED,eAAO,MAAM,aAAa,0IASxB,CAAC;AAEH,OAAO,QAAQ,gCAAgC,CAAC;IAC9C,UAAU,WAAW;QACnB,OAAO,EAAE,OAAO,aAAa,CAAC;KAC/B;IACD,UAAU,UAAU;QAClB,OAAO,CAAC,EAAE,iBAAiB,CAAC;KAC7B;CACF;AAQD,wBAAgB,aAAa,CAC3B,UAAU,GAAE,oBAAyB,GACpC,cAAc,CAkChB"}
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../src/modules/ambient/module.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,aAAa,EACnB,MAAM,UAAU,CAAC;AAIlB,OAAO,KAAK,EACV,aAAa,EAGb,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACf,MAAM,SAAS,CAAC;AAMjB,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,gBAAgB,GAAG,IAAI,EAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,GACvB,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAc/B;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,gBAAgB,CAKtE;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,gBAAgB,GAAG,IAAI,EAC9B,IAAI,EAAE,aAAa,GAClB,cAAc,CAahB;AAED,eAAO,MAAM,aAAa,0IASxB,CAAC;AAEH,OAAO,QAAQ,gCAAgC,CAAC;IAC9C,UAAU,WAAW;QACnB,OAAO,EAAE,OAAO,aAAa,CAAC;KAC/B;IACD,UAAU,UAAU;QAClB,OAAO,CAAC,EAAE,iBAAiB,CAAC;KAC7B;CACF;AAQD,wBAAgB,aAAa,CAC3B,UAAU,GAAE,oBAAyB,GACpC,cAAc,CAkChB"}
@@ -0,0 +1,36 @@
1
+ import type { OklchColor } from "./types";
2
+ export type Lab = [l: number, a: number, b: number];
3
+ export type Rgb = [r: number, g: number, b: number];
4
+ export declare function clamp(value: number, min: number, max: number): number;
5
+ export declare function smoothstep(edge0: number, edge1: number, value: number): number;
6
+ /** 8-bit sRGB channels → OKLab. */
7
+ export declare function srgbToOklab(r: number, g: number, b: number): Lab;
8
+ /** OKLCH → linear sRGB; channels outside 0–1 mean the colour is out of gamut. */
9
+ export declare function oklchToLinearSrgb(l: number, c: number, h: number): Rgb;
10
+ export declare function labToLch([l, a, b]: Lab): OklchColor;
11
+ /**
12
+ * The most chroma sRGB can show at this lightness and hue (binary search on
13
+ * the gamut boundary). Dark blues and purples have far more room than dark
14
+ * greens or yellows, which is why one fixed chroma never looks right.
15
+ */
16
+ export declare function maxChroma(l: number, h: number): number;
17
+ /** Share of the available chroma a colour uses (0 grey … 1 on the gamut edge). */
18
+ export declare function relativeChroma({ c, h, l }: OklchColor): number;
19
+ export declare function hueDistance(a: number, b: number): number;
20
+ /** WCAG 2 relative luminance of an OKLCH colour (gamut-clipped). */
21
+ export declare function luminance({ c, h, l }: OklchColor): number;
22
+ export declare function contrastRatio(a: OklchColor, b: OklchColor): number;
23
+ export declare function formatOklch({ c, h, l }: OklchColor): string;
24
+ /**
25
+ * A tone of a hue at lightness `l`, using `rel` of the chroma sRGB allows
26
+ * there (never more than `cap`). This keeps a hue's character across a whole
27
+ * ramp: dark tones of blue stay blue instead of collapsing to grey.
28
+ */
29
+ export declare function toneOf(h: number, l: number, rel: number, cap?: number): OklchColor;
30
+ /**
31
+ * Text colour for a background: a near-white or near-black carrying a hint of
32
+ * the background's hue, pushed toward pure white / black until it reaches
33
+ * `minContrast` (WCAG 2 ratio).
34
+ */
35
+ export declare function onColorFor(background: OklchColor, minContrast?: number): OklchColor;
36
+ //# sourceMappingURL=oklab.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oklab.d.ts","sourceRoot":"","sources":["../../../src/modules/ambient/oklab.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAK1C,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;AACpD,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;AAUpD,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAErE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAG9E;AAED,mCAAmC;AACnC,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,GAAG,CAchE;AAED,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,GAAG,CAWtE;AAED,wBAAgB,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,UAAU,CAInD;AAID;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAUtD;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,UAAU,GAAG,MAAM,CAG9D;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAGxD;AAED,oEAAoE;AACpE,wBAAgB,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,UAAU,GAAG,MAAM,CAGzD;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,MAAM,CAIlE;AAOD,wBAAgB,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,UAAU,GAAG,MAAM,CAG3D;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CACpB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,GAAG,EAAE,MAAM,EACX,GAAG,SAAM,GACR,UAAU,CAGZ;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,UAAU,EAAE,UAAU,EACtB,WAAW,SAAM,GAChB,UAAU,CAcZ"}
@@ -0,0 +1,28 @@
1
+ import type { AmbientAnalysisOptions, AmbientPalette, AmbientPixels } from "./types";
2
+ export interface AmbientExtractRequest {
3
+ analysis: AmbientAnalysisOptions;
4
+ /** Absolute URL of a proxy to retry through, if any. */
5
+ proxyUrl: string | null;
6
+ /** Absolute image URL. */
7
+ src: string;
8
+ }
9
+ export type AmbientExtractResult = {
10
+ palette: AmbientPalette | null;
11
+ supported: true;
12
+ } | {
13
+ supported: false;
14
+ };
15
+ type Context2D = OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D;
16
+ export declare function fetchImageBlob(src: string, proxyUrl: string | null): Promise<Blob | null>;
17
+ export declare function createContext2D(width: number, height: number): Context2D | null;
18
+ export declare function readPixels(image: CanvasImageSource, sourceWidth: number, sourceHeight: number, size: number): AmbientPixels | null;
19
+ /**
20
+ * Decodes off the main thread: `createImageBitmap` decodes (and, where
21
+ * supported, downscales) in the browser's image pipeline, so only a small
22
+ * bitmap is ever drawn.
23
+ */
24
+ export declare function decodeBlob(blob: Blob, size: number): Promise<AmbientPixels | null>;
25
+ export declare const canDecodeHere: () => boolean;
26
+ export declare function extractHere(request: AmbientExtractRequest): Promise<AmbientExtractResult>;
27
+ export {};
28
+ //# sourceMappingURL=pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../../src/modules/ambient/pipeline.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,sBAAsB,EACtB,cAAc,EACd,aAAa,EACd,MAAM,SAAS,CAAC;AAMjB,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,sBAAsB,CAAC;IACjC,wDAAwD;IACxD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,IAAI,CAAA;CAAE,GACnD;IAAE,SAAS,EAAE,KAAK,CAAA;CAAE,CAAC;AAEzB,KAAK,SAAS,GAAG,iCAAiC,GAAG,wBAAwB,CAAC;AAE9E,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GAAG,IAAI,GACtB,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAmCtB;AAUD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAa/E;AAED,wBAAgB,UAAU,CACxB,KAAK,EAAE,iBAAiB,EACxB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,GACX,aAAa,GAAG,IAAI,CAMtB;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAgB/B;AAED,eAAO,MAAM,aAAa,eAEkD,CAAC;AAE7E,wBAAsB,WAAW,CAC/B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAa/B"}
@@ -0,0 +1,22 @@
1
+ export interface KMeansResult {
2
+ /** Index of the cluster each point belongs to. */
3
+ assignment: Int32Array;
4
+ /** `k × 3` OKLab centroids. */
5
+ centroids: Float64Array;
6
+ /** Number of clusters actually found (≤ the requested k). */
7
+ k: number;
8
+ }
9
+ export interface KMeansOptions {
10
+ iterations?: number;
11
+ /** Weight of ΔL² against Δa² + Δb²; below 1 favours hue over lightness. */
12
+ lightnessWeight?: number;
13
+ }
14
+ /**
15
+ * Weighted k-means in OKLab with deterministic seeding (the heaviest point,
16
+ * then repeatedly the point that is heaviest × furthest from every seed), so
17
+ * the same pixels always give the same palette on the server and the client.
18
+ *
19
+ * `points` holds `n × 3` OKLab values and `weights` one weight per point.
20
+ */
21
+ export declare function kmeans(points: Float64Array, weights: Float64Array, requested: number, { iterations, lightnessWeight }?: KMeansOptions): KMeansResult;
22
+ //# sourceMappingURL=quantize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quantize.d.ts","sourceRoot":"","sources":["../../../src/modules/ambient/quantize.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,kDAAkD;IAClD,UAAU,EAAE,UAAU,CAAC;IACvB,+BAA+B;IAC/B,SAAS,EAAE,YAAY,CAAC;IACxB,6DAA6D;IAC7D,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,MAAM,CACpB,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,YAAY,EACrB,SAAS,EAAE,MAAM,EACjB,EAAE,UAAe,EAAE,eAAsB,EAAE,GAAE,aAAkB,GAC9D,YAAY,CA2Ed"}
@@ -0,0 +1,8 @@
1
+ /** Lower-cased, without the trailing dot(s) and IPv6 brackets. */
2
+ export declare function normalizeHost(hostname: string): string;
3
+ /** `true` for loopback, private, link-local, CGNAT, multicast and reserved IPs. */
4
+ export declare function isPrivateAddress(address: string): boolean;
5
+ export declare const isIpLiteral: (hostname: string) => boolean;
6
+ /** A host name that only means something on a private network. */
7
+ export declare function isPrivateHostname(hostname: string): boolean;
8
+ //# sourceMappingURL=address.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../../../../src/modules/ambient/server/address.ts"],"names":[],"mappings":"AAKA,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEtD;AA+DD,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAMzD;AAED,eAAO,MAAM,WAAW,GAAI,UAAU,MAAM,YAG3C,CAAC;AAEF,kEAAkE;AAClE,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAK3D"}
@@ -0,0 +1,53 @@
1
+ import type { AmbientAnalysisOptions, AmbientPalette, AmbientPixels } from "../types";
2
+ export { analyzeAmbientPixels, findContentBounds, fitSample } from "../analyze";
3
+ export { isPrivateAddress, isPrivateHostname } from "./address";
4
+ export { configureAmbient, getAmbientSettings } from "../settings";
5
+ export { contrastRatio, formatOklch, maxChroma, onColorFor, srgbToOklab, toneOf, } from "../oklab";
6
+ export type * from "../types";
7
+ /** Decodes image bytes into RGBA pixels no larger than `size` on the long side. */
8
+ export type AmbientDecoder = (bytes: Uint8Array, size: number) => Promise<AmbientPixels>;
9
+ export interface AmbientServerOptions {
10
+ analysis?: Partial<AmbientAnalysisOptions>;
11
+ /** Which URLs may be fetched. Default: public http(s) hosts only. */
12
+ allow?: (url: URL) => boolean;
13
+ /** Keep results in an in-process cache (default `true`). */
14
+ cache?: boolean;
15
+ /** Default: `sharp` (loaded on first use; it ships with Next.js). */
16
+ decode?: AmbientDecoder;
17
+ fetch?: typeof fetch;
18
+ /** Extra fetch options, e.g. `{ next: { revalidate: 86400 } }`. */
19
+ init?: RequestInit;
20
+ maxBytes?: number;
21
+ /**
22
+ * Resolves a host name to its IP addresses, checked before every request
23
+ * (redirects included): a request whose host resolves to any loopback,
24
+ * private, link-local or reserved address is refused. Default: `node:dns`.
25
+ * `false` skips the check (only do that behind an `allow` list).
26
+ */
27
+ resolve?: ((hostname: string) => Promise<string[]>) | false;
28
+ timeoutMs?: number;
29
+ }
30
+ /**
31
+ * Public http(s) URLs only: no credentials, no localhost / private / link-local
32
+ * names or IP literals (in any spelling the URL parser accepts). Host names
33
+ * are also resolved and checked before fetching (`resolve`).
34
+ */
35
+ export declare function isPublicImageUrl(url: URL): boolean;
36
+ /** Thrown (not swallowed) when no decoder is available: a setup error, not a bad image. */
37
+ export declare class AmbientDecoderMissingError extends Error {
38
+ name: string;
39
+ }
40
+ /** The default decoder: `sharp`, resized inside libvips. */
41
+ export declare const sharpDecoder: AmbientDecoder;
42
+ /** The palette of image bytes (JPEG, PNG, WebP, AVIF… whatever the decoder reads). */
43
+ export declare function extractAmbientPaletteFromBytes(bytes: Uint8Array, options?: Pick<AmbientServerOptions, "analysis" | "decode">): Promise<AmbientPalette>;
44
+ /**
45
+ * Fetches an image and returns its palette, or `null` when it cannot be
46
+ * fetched or decoded. `source` is the URL, so a client theme given the same
47
+ * image and this palette as `initialPalette` does not extract it again.
48
+ *
49
+ * Wrap it in the app's cache (`"use cache"`, `unstable_cache`…) to keep
50
+ * palettes across requests; an in-process cache is kept as well.
51
+ */
52
+ export declare function extractAmbientPalette(src: string | URL, options?: AmbientServerOptions): Promise<AmbientPalette | null>;
53
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/modules/ambient/server/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,sBAAsB,EACtB,cAAc,EACd,aAAa,EACd,MAAM,UAAU,CAAC;AAMlB,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EACL,aAAa,EACb,WAAW,EACX,SAAS,EACT,UAAU,EACV,WAAW,EACX,MAAM,GACP,MAAM,UAAU,CAAC;AAClB,mBAAmB,UAAU,CAAC;AAE9B,mFAAmF;AACnF,MAAM,MAAM,cAAc,GAAG,CAC3B,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,MAAM,KACT,OAAO,CAAC,aAAa,CAAC,CAAC;AAE5B,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC3C,qEAAqE;IACrE,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;IAC9B,4DAA4D;IAC5D,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,qEAAqE;IACrE,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,mEAAmE;IACnE,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAOlD;AAqCD,2FAA2F;AAC3F,qBAAa,0BAA2B,SAAQ,KAAK;IAC1C,IAAI,SAAgC;CAC9C;AAkBD,4DAA4D;AAC5D,eAAO,MAAM,YAAY,EAAE,cAS1B,CAAC;AA6BF,sFAAsF;AACtF,wBAAsB,8BAA8B,CAClD,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,IAAI,CAAC,oBAAoB,EAAE,UAAU,GAAG,QAAQ,CAAM,GAC9D,OAAO,CAAC,cAAc,CAAC,CAIzB;AAoDD;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAgChC"}
@@ -0,0 +1,221 @@
1
+ import { resolveAnalysis, analyzeAmbientPixels } from '../../../chunk-6SG7V77J.js';
2
+ export { analyzeAmbientPixels, configureAmbient, contrastRatio, findContentBounds, fitSample, formatOklch, getAmbientSettings, maxChroma, onColorFor, srgbToOklab, toneOf } from '../../../chunk-6SG7V77J.js';
3
+
4
+ // src/modules/ambient/server/address.ts
5
+ var PRIVATE_NAMES = /(^|\.)(localhost|local|internal|intranet|lan|home\.arpa|localdomain)$/;
6
+ function normalizeHost(hostname) {
7
+ return hostname.toLowerCase().replace(/\.+$/, "").replace(/^\[|\]$/g, "");
8
+ }
9
+ function parseIPv4(value) {
10
+ const parts = value.split(".");
11
+ if (parts.length !== 4) return null;
12
+ const bytes = parts.map((part) => /^\d{1,3}$/.test(part) ? Number(part) : NaN);
13
+ return bytes.every((byte) => byte >= 0 && byte <= 255) ? bytes : null;
14
+ }
15
+ function isPrivateIPv4([a, b, c]) {
16
+ return a === 0 || // "this network"
17
+ a === 10 || a === 127 || a === 100 && b >= 64 && b <= 127 || // CGNAT
18
+ a === 169 && b === 254 || // link-local, cloud metadata
19
+ a === 172 && b >= 16 && b <= 31 || a === 192 && b === 168 || a === 192 && b === 0 && c === 0 || // IETF protocol assignments
20
+ a === 198 && (b === 18 || b === 19) || // benchmarking
21
+ a >= 224;
22
+ }
23
+ function parseIPv6(value) {
24
+ let text = value.split("%")[0];
25
+ const tail = text.match(/^(.*:)(\d+\.\d+\.\d+\.\d+)$/);
26
+ if (tail) {
27
+ const v4 = parseIPv4(tail[2]);
28
+ if (!v4) return null;
29
+ text = `${tail[1]}${(v4[0] << 8 | v4[1]).toString(16)}:${(v4[2] << 8 | v4[3]).toString(16)}`;
30
+ }
31
+ const halves = text.split("::");
32
+ if (halves.length > 2) return null;
33
+ const read = (part) => part ? part.split(":") : [];
34
+ const head = read(halves[0]);
35
+ const rest = halves.length === 2 ? read(halves[1]) : [];
36
+ const missing = 8 - head.length - rest.length;
37
+ if (halves.length === 1 ? missing !== 0 : missing < 1) return null;
38
+ const groups = [...head, ...Array(halves.length === 2 ? missing : 0).fill("0"), ...rest];
39
+ const words = groups.map((group) => /^[0-9a-f]{1,4}$/.test(group) ? parseInt(group, 16) : NaN);
40
+ return words.length === 8 && words.every((word) => word >= 0) ? words : null;
41
+ }
42
+ function isPrivateIPv6(words) {
43
+ const [w0, w1, w2, w3, w4, w5, w6, w7] = words;
44
+ const embedded = () => [w6 >> 8, w6 & 255, w7 >> 8, w7 & 255];
45
+ if (words.slice(0, 7).every((word) => word === 0)) return w7 <= 1;
46
+ if (w0 === 0 && w1 === 0 && w2 === 0 && w3 === 0 && w4 === 0 && (w5 === 65535 || w5 === 0)) {
47
+ return isPrivateIPv4(embedded());
48
+ }
49
+ if (w0 === 100 && w1 === 65435) return isPrivateIPv4(embedded());
50
+ if (w0 === 8194) return isPrivateIPv4([w1 >> 8, w1 & 255, w2 >> 8, w2 & 255]);
51
+ return (w0 & 65024) === 64512 || // unique local
52
+ (w0 & 65472) === 65152 || // link-local
53
+ (w0 & 65280) === 65280 || // multicast
54
+ w0 === 8193 && w1 === 3512;
55
+ }
56
+ function isPrivateAddress(address) {
57
+ const host = normalizeHost(address);
58
+ const v4 = parseIPv4(host);
59
+ if (v4) return isPrivateIPv4(v4);
60
+ const v6 = parseIPv6(host);
61
+ return v6 ? isPrivateIPv6(v6) : false;
62
+ }
63
+ var isIpLiteral = (hostname) => {
64
+ const host = normalizeHost(hostname);
65
+ return parseIPv4(host) !== null || parseIPv6(host) !== null;
66
+ };
67
+ function isPrivateHostname(hostname) {
68
+ const host = normalizeHost(hostname);
69
+ if (!host) return true;
70
+ if (isIpLiteral(host)) return isPrivateAddress(host);
71
+ return PRIVATE_NAMES.test(host) || !host.includes(".");
72
+ }
73
+
74
+ // src/modules/ambient/server/index.ts
75
+ var MAX_BYTES = 12 * 1024 * 1024;
76
+ var TIMEOUT_MS = 8e3;
77
+ var CACHE_LIMIT = 500;
78
+ function isPublicImageUrl(url) {
79
+ return (url.protocol === "https:" || url.protocol === "http:") && !url.username && !url.password && !isPrivateHostname(url.hostname);
80
+ }
81
+ async function lookupAll(hostname) {
82
+ const { lookup } = await import('dns/promises');
83
+ return (await lookup(hostname, { all: true, verbatim: true })).map(
84
+ (entry) => entry.address
85
+ );
86
+ }
87
+ async function reachesOnlyPublic(url, resolve) {
88
+ if (resolve === false) return true;
89
+ const host = normalizeHost(url.hostname);
90
+ try {
91
+ const addresses = isIpLiteral(host) ? [host] : await (resolve ?? lookupAll)(host);
92
+ return addresses.length > 0 && !addresses.some(isPrivateAddress);
93
+ } catch {
94
+ return false;
95
+ }
96
+ }
97
+ var AmbientDecoderMissingError = class extends Error {
98
+ name = "AmbientDecoderMissingError";
99
+ };
100
+ var sharpModule = null;
101
+ var SHARP = "sharp";
102
+ function loadSharp() {
103
+ sharpModule ??= import(
104
+ /* webpackIgnore: true */
105
+ /* turbopackIgnore: true */
106
+ SHARP
107
+ ).then((mod) => mod.default ?? mod).catch((error) => {
108
+ sharpModule = null;
109
+ throw new AmbientDecoderMissingError(
110
+ "ambient/server: `sharp` is not installed. Install it or pass `decode`.",
111
+ { cause: error }
112
+ );
113
+ });
114
+ return sharpModule;
115
+ }
116
+ var sharpDecoder = async (bytes, size) => {
117
+ const sharp = await loadSharp();
118
+ const { data, info } = await sharp(bytes, { failOn: "none" }).rotate().resize(size, size, { fit: "inside", withoutEnlargement: true }).ensureAlpha().raw().toBuffer({ resolveWithObject: true });
119
+ return { data, height: info.height, width: info.width };
120
+ };
121
+ async function readLimited(response, maxBytes) {
122
+ const declared = Number(response.headers.get("content-length"));
123
+ if (declared > maxBytes) throw new Error("ambient/server: image too large");
124
+ if (!response.body) return new Uint8Array(await response.arrayBuffer());
125
+ const reader = response.body.getReader();
126
+ const chunks = [];
127
+ let length = 0;
128
+ for (; ; ) {
129
+ const { done, value } = await reader.read();
130
+ if (done) break;
131
+ length += value.byteLength;
132
+ if (length > maxBytes) {
133
+ await reader.cancel();
134
+ throw new Error("ambient/server: image too large");
135
+ }
136
+ chunks.push(value);
137
+ }
138
+ const bytes = new Uint8Array(length);
139
+ let offset = 0;
140
+ for (const chunk of chunks) {
141
+ bytes.set(chunk, offset);
142
+ offset += chunk.byteLength;
143
+ }
144
+ return bytes;
145
+ }
146
+ async function extractAmbientPaletteFromBytes(bytes, options = {}) {
147
+ const analysis = resolveAnalysis(options.analysis);
148
+ const pixels = await (options.decode ?? sharpDecoder)(bytes, analysis.sampleSize);
149
+ return analyzeAmbientPixels(pixels, analysis);
150
+ }
151
+ var cache = /* @__PURE__ */ new Map();
152
+ var inFlight = /* @__PURE__ */ new Map();
153
+ function remember(key, palette) {
154
+ cache.delete(key);
155
+ while (cache.size >= CACHE_LIMIT) {
156
+ const oldest = cache.keys().next().value;
157
+ if (oldest === void 0) break;
158
+ cache.delete(oldest);
159
+ }
160
+ cache.set(key, palette);
161
+ }
162
+ async function fetchAndExtract(url, options) {
163
+ const allow = options.allow ?? isPublicImageUrl;
164
+ const doFetch = options.fetch ?? fetch;
165
+ const signal = AbortSignal.timeout(options.timeoutMs ?? TIMEOUT_MS);
166
+ let current = url;
167
+ for (let hop = 0; hop <= 5; hop++) {
168
+ if (!allow(current)) return null;
169
+ if (!await reachesOnlyPublic(current, options.resolve)) return null;
170
+ const response = await doFetch(current, {
171
+ ...options.init,
172
+ redirect: "manual",
173
+ signal
174
+ });
175
+ if (response.status >= 300 && response.status < 400) {
176
+ const location = response.headers.get("location");
177
+ await response.body?.cancel();
178
+ if (!location) return null;
179
+ current = new URL(location, current);
180
+ continue;
181
+ }
182
+ if (!response.ok) return null;
183
+ const type = response.headers.get("content-type") ?? "";
184
+ if (type && !type.toLowerCase().startsWith("image/")) return null;
185
+ const bytes = await readLimited(response, options.maxBytes ?? MAX_BYTES);
186
+ const palette = await extractAmbientPaletteFromBytes(bytes, options);
187
+ return { ...palette, source: url.href };
188
+ }
189
+ return null;
190
+ }
191
+ async function extractAmbientPalette(src, options = {}) {
192
+ let url;
193
+ try {
194
+ url = new URL(src);
195
+ } catch {
196
+ return null;
197
+ }
198
+ const useCache = options.cache !== false;
199
+ const key = options.analysis ? `${url.href}#${JSON.stringify(options.analysis)}` : url.href;
200
+ if (useCache) {
201
+ const hit = cache.get(key);
202
+ if (hit) return hit;
203
+ const pending = inFlight.get(key);
204
+ if (pending) return pending;
205
+ }
206
+ const task = fetchAndExtract(url, options).catch((error) => {
207
+ if (error instanceof AmbientDecoderMissingError) throw error;
208
+ return null;
209
+ });
210
+ if (!useCache) return task;
211
+ const shared = task.then((palette) => {
212
+ if (palette) remember(key, palette);
213
+ return palette;
214
+ }).finally(() => inFlight.delete(key));
215
+ inFlight.set(key, shared);
216
+ return shared;
217
+ }
218
+
219
+ export { AmbientDecoderMissingError, extractAmbientPalette, extractAmbientPaletteFromBytes, isPrivateAddress, isPrivateHostname, isPublicImageUrl, sharpDecoder };
220
+ //# sourceMappingURL=index.js.map
221
+ //# sourceMappingURL=index.js.map