@omerdlw/base-framework 1.0.6 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/dist/atoms/index.js +1 -103
  2. package/dist/atoms/index.js.map +1 -1
  3. package/dist/chunk-3BUP64Q6.js +105 -0
  4. package/dist/chunk-3BUP64Q6.js.map +1 -0
  5. package/dist/chunk-3MSK4XGK.js +9888 -0
  6. package/dist/chunk-3MSK4XGK.js.map +1 -0
  7. package/dist/chunk-4GMQKD6F.js +353 -0
  8. package/dist/chunk-4GMQKD6F.js.map +1 -0
  9. package/dist/chunk-65ZB4QTQ.js +888 -0
  10. package/dist/chunk-65ZB4QTQ.js.map +1 -0
  11. package/dist/chunk-6SG7V77J.js +577 -0
  12. package/dist/chunk-6SG7V77J.js.map +1 -0
  13. package/dist/chunk-7HQMXTNP.js +419 -0
  14. package/dist/chunk-7HQMXTNP.js.map +1 -0
  15. package/dist/chunk-7TAVYJ3A.js +371 -0
  16. package/dist/chunk-7TAVYJ3A.js.map +1 -0
  17. package/dist/chunk-AQ4BNXA2.js +349 -0
  18. package/dist/chunk-AQ4BNXA2.js.map +1 -0
  19. package/dist/chunk-CGHZSSFR.js +2166 -0
  20. package/dist/chunk-CGHZSSFR.js.map +1 -0
  21. package/dist/chunk-DGCQWQLZ.js +61 -0
  22. package/dist/chunk-DGCQWQLZ.js.map +1 -0
  23. package/dist/chunk-FIMPHODX.js +67 -0
  24. package/dist/chunk-FIMPHODX.js.map +1 -0
  25. package/dist/chunk-GF7TUX5I.js +1889 -0
  26. package/dist/chunk-GF7TUX5I.js.map +1 -0
  27. package/dist/chunk-JELG4JLT.js +454 -0
  28. package/dist/chunk-JELG4JLT.js.map +1 -0
  29. package/dist/chunk-K676GL7Z.js +51 -0
  30. package/dist/chunk-K676GL7Z.js.map +1 -0
  31. package/dist/chunk-KKQT46TP.js +26 -0
  32. package/dist/chunk-KKQT46TP.js.map +1 -0
  33. package/dist/chunk-QI3ALLIB.js +38 -0
  34. package/dist/chunk-QI3ALLIB.js.map +1 -0
  35. package/dist/chunk-QXR55VVS.js +1139 -0
  36. package/dist/chunk-QXR55VVS.js.map +1 -0
  37. package/dist/chunk-R2YGFJDJ.js +408 -0
  38. package/dist/chunk-R2YGFJDJ.js.map +1 -0
  39. package/dist/chunk-RFZQWLC5.js +27 -0
  40. package/dist/chunk-RFZQWLC5.js.map +1 -0
  41. package/dist/chunk-SYAVGTOX.js +521 -0
  42. package/dist/chunk-SYAVGTOX.js.map +1 -0
  43. package/dist/chunk-TV3WEF5G.js +784 -0
  44. package/dist/chunk-TV3WEF5G.js.map +1 -0
  45. package/dist/chunk-XASQT4CQ.js +280 -0
  46. package/dist/chunk-XASQT4CQ.js.map +1 -0
  47. package/dist/error/index.js +5 -682
  48. package/dist/error/index.js.map +1 -1
  49. package/dist/error/reporter.d.ts.map +1 -1
  50. package/dist/error/theme.d.ts +1 -1
  51. package/dist/error/theme.d.ts.map +1 -1
  52. package/dist/events.js +1 -7
  53. package/dist/events.js.map +1 -1
  54. package/dist/hooks/index.js +1 -358
  55. package/dist/hooks/index.js.map +1 -1
  56. package/dist/hooks/use-global-event.d.ts +1 -1
  57. package/dist/index.js +18 -20029
  58. package/dist/index.js.map +1 -1
  59. package/dist/kernel/index.js +2 -2035
  60. package/dist/kernel/index.js.map +1 -1
  61. package/dist/kernel/types.d.ts +1 -1
  62. package/dist/modules/ambient/analyze.d.ts +46 -0
  63. package/dist/modules/ambient/analyze.d.ts.map +1 -0
  64. package/dist/modules/ambient/constants.d.ts +1 -5
  65. package/dist/modules/ambient/constants.d.ts.map +1 -1
  66. package/dist/modules/ambient/context.d.ts.map +1 -1
  67. package/dist/modules/ambient/dom.d.ts +11 -12
  68. package/dist/modules/ambient/dom.d.ts.map +1 -1
  69. package/dist/modules/ambient/extractor.d.ts +10 -10
  70. package/dist/modules/ambient/extractor.d.ts.map +1 -1
  71. package/dist/modules/ambient/hooks.d.ts +1 -1
  72. package/dist/modules/ambient/hooks.d.ts.map +1 -1
  73. package/dist/modules/ambient/index.d.ts +6 -4
  74. package/dist/modules/ambient/index.d.ts.map +1 -1
  75. package/dist/modules/ambient/index.js +7 -762
  76. package/dist/modules/ambient/index.js.map +1 -1
  77. package/dist/modules/ambient/module.d.ts +1 -1
  78. package/dist/modules/ambient/module.d.ts.map +1 -1
  79. package/dist/modules/ambient/oklab.d.ts +36 -0
  80. package/dist/modules/ambient/oklab.d.ts.map +1 -0
  81. package/dist/modules/ambient/pipeline.d.ts +28 -0
  82. package/dist/modules/ambient/pipeline.d.ts.map +1 -0
  83. package/dist/modules/ambient/quantize.d.ts +22 -0
  84. package/dist/modules/ambient/quantize.d.ts.map +1 -0
  85. package/dist/modules/ambient/server/address.d.ts +8 -0
  86. package/dist/modules/ambient/server/address.d.ts.map +1 -0
  87. package/dist/modules/ambient/server/index.d.ts +53 -0
  88. package/dist/modules/ambient/server/index.d.ts.map +1 -0
  89. package/dist/modules/ambient/server/index.js +221 -0
  90. package/dist/modules/ambient/server/index.js.map +1 -0
  91. package/dist/modules/ambient/settings.d.ts +19 -0
  92. package/dist/modules/ambient/settings.d.ts.map +1 -0
  93. package/dist/modules/ambient/types.d.ts +105 -9
  94. package/dist/modules/ambient/types.d.ts.map +1 -1
  95. package/dist/modules/ambient/worker/index.d.ts +15 -0
  96. package/dist/modules/ambient/worker/index.d.ts.map +1 -0
  97. package/dist/modules/ambient/worker/index.js +114 -0
  98. package/dist/modules/ambient/worker/index.js.map +1 -0
  99. package/dist/modules/background/constants.d.ts +2 -2
  100. package/dist/modules/background/constants.d.ts.map +1 -1
  101. package/dist/modules/background/hooks.d.ts +1 -1
  102. package/dist/modules/background/index.js +6 -3078
  103. package/dist/modules/background/index.js.map +1 -1
  104. package/dist/modules/background/motion.d.ts +9 -7
  105. package/dist/modules/background/motion.d.ts.map +1 -1
  106. package/dist/modules/background/overlay.d.ts +3 -8
  107. package/dist/modules/background/overlay.d.ts.map +1 -1
  108. package/dist/modules/background/types.d.ts +16 -2
  109. package/dist/modules/background/types.d.ts.map +1 -1
  110. package/dist/modules/context-menu/constants.d.ts +2 -2
  111. package/dist/modules/context-menu/constants.d.ts.map +1 -1
  112. package/dist/modules/context-menu/hooks.d.ts +1 -1
  113. package/dist/modules/context-menu/index.js +10 -1896
  114. package/dist/modules/context-menu/index.js.map +1 -1
  115. package/dist/modules/context-menu/motion.d.ts +1 -8
  116. package/dist/modules/context-menu/motion.d.ts.map +1 -1
  117. package/dist/modules/context-menu/overlay.d.ts.map +1 -1
  118. package/dist/modules/context-menu/types.d.ts +16 -2
  119. package/dist/modules/context-menu/types.d.ts.map +1 -1
  120. package/dist/modules/controls/constants.d.ts +1 -1
  121. package/dist/modules/controls/constants.d.ts.map +1 -1
  122. package/dist/modules/controls/entries.d.ts +1 -1
  123. package/dist/modules/controls/hooks.d.ts +1 -1
  124. package/dist/modules/controls/index.js +4 -1110
  125. package/dist/modules/controls/index.js.map +1 -1
  126. package/dist/modules/controls/overlay.d.ts +1 -1
  127. package/dist/modules/controls/types.d.ts +2 -2
  128. package/dist/modules/dock/cards.d.ts +708 -24
  129. package/dist/modules/dock/cards.d.ts.map +1 -1
  130. package/dist/modules/dock/constants.d.ts +2 -2
  131. package/dist/modules/dock/constants.d.ts.map +1 -1
  132. package/dist/modules/dock/helpers.d.ts +2 -2
  133. package/dist/modules/dock/hooks.d.ts +2 -2
  134. package/dist/modules/dock/index.d.ts +1 -1
  135. package/dist/modules/dock/index.d.ts.map +1 -1
  136. package/dist/modules/dock/index.js +9 -12132
  137. package/dist/modules/dock/index.js.map +1 -1
  138. package/dist/modules/dock/module.d.ts +1 -1
  139. package/dist/modules/dock/motion.d.ts +41 -915
  140. package/dist/modules/dock/motion.d.ts.map +1 -1
  141. package/dist/modules/dock/overlay.d.ts.map +1 -1
  142. package/dist/modules/dock/runtime/dock.d.ts +1 -23
  143. package/dist/modules/dock/runtime/dock.d.ts.map +1 -1
  144. package/dist/modules/dock/styles.d.ts +4 -4
  145. package/dist/modules/dock/surface/hooks.d.ts +5 -20
  146. package/dist/modules/dock/surface/hooks.d.ts.map +1 -1
  147. package/dist/modules/dock/surface/machine.d.ts +4 -3
  148. package/dist/modules/dock/surface/machine.d.ts.map +1 -1
  149. package/dist/modules/dock/surface/stack.d.ts.map +1 -1
  150. package/dist/modules/dock/types.d.ts +158 -3
  151. package/dist/modules/dock/types.d.ts.map +1 -1
  152. package/dist/modules/index.js +16 -17883
  153. package/dist/modules/index.js.map +1 -1
  154. package/dist/modules/loading/constants.d.ts +1 -1
  155. package/dist/modules/loading/constants.d.ts.map +1 -1
  156. package/dist/modules/loading/context.d.ts +1 -1
  157. package/dist/modules/loading/hooks.d.ts +1 -1
  158. package/dist/modules/loading/index.js +5 -1153
  159. package/dist/modules/loading/index.js.map +1 -1
  160. package/dist/modules/loading/types.d.ts +2 -2
  161. package/dist/modules/media/context.d.ts +1 -1
  162. package/dist/modules/media/index.js +3 -570
  163. package/dist/modules/media/index.js.map +1 -1
  164. package/dist/modules/media/types.d.ts +2 -2
  165. package/dist/modules/modal/constants.d.ts +2 -2
  166. package/dist/modules/modal/constants.d.ts.map +1 -1
  167. package/dist/modules/modal/context.d.ts +1 -1
  168. package/dist/modules/modal/hooks.d.ts +3 -3
  169. package/dist/modules/modal/index.js +8 -2355
  170. package/dist/modules/modal/index.js.map +1 -1
  171. package/dist/modules/modal/motion.d.ts +3 -8
  172. package/dist/modules/modal/motion.d.ts.map +1 -1
  173. package/dist/modules/modal/overlay.d.ts.map +1 -1
  174. package/dist/modules/modal/types.d.ts +21 -0
  175. package/dist/modules/modal/types.d.ts.map +1 -1
  176. package/dist/modules/notification/constants.d.ts +2 -2
  177. package/dist/modules/notification/constants.d.ts.map +1 -1
  178. package/dist/modules/notification/context.d.ts +1 -1
  179. package/dist/modules/notification/hooks.d.ts +1 -1
  180. package/dist/modules/notification/index.js +4 -828
  181. package/dist/modules/notification/index.js.map +1 -1
  182. package/dist/modules/notification/motion.d.ts +1 -7
  183. package/dist/modules/notification/motion.d.ts.map +1 -1
  184. package/dist/modules/notification/overlay.d.ts.map +1 -1
  185. package/dist/modules/notification/types.d.ts +9 -1
  186. package/dist/modules/notification/types.d.ts.map +1 -1
  187. package/dist/overlay-TZ6L52A5.js +9 -0
  188. package/dist/overlay-TZ6L52A5.js.map +1 -0
  189. package/dist/provider.d.ts +1 -1
  190. package/dist/provider.d.ts.map +1 -1
  191. package/dist/provider.js +6 -1968
  192. package/dist/provider.js.map +1 -1
  193. package/dist/result.js +2 -63
  194. package/dist/result.js.map +1 -1
  195. package/dist/theme.d.ts +45 -8
  196. package/dist/theme.d.ts.map +1 -1
  197. package/dist/theme.js +3 -41
  198. package/dist/theme.js.map +1 -1
  199. package/dist/tokens/index.d.ts +1 -0
  200. package/dist/tokens/index.d.ts.map +1 -1
  201. package/dist/tokens/index.js +126 -155
  202. package/dist/tokens/index.js.map +1 -1
  203. package/dist/tokens/motion-config.d.ts +44 -0
  204. package/dist/tokens/motion-config.d.ts.map +1 -0
  205. package/dist/tokens/motion.d.ts +23 -174
  206. package/dist/tokens/motion.d.ts.map +1 -1
  207. package/dist/utils/index.js +4 -82
  208. package/dist/utils/index.js.map +1 -1
  209. package/dist/utils/report.d.ts.map +1 -1
  210. package/docs/README.md +1 -0
  211. package/docs/architecture-and-rules.md +4 -3
  212. package/docs/core-engine.md +7 -10
  213. package/docs/getting-started.md +4 -2
  214. package/docs/modules/ambient.md +194 -80
  215. package/docs/modules/background.md +3 -3
  216. package/docs/modules/context-menu.md +2 -2
  217. package/docs/modules/dock.md +8 -5
  218. package/docs/modules/modal.md +2 -2
  219. package/docs/modules/notification.md +2 -2
  220. package/docs/theming.md +81 -9
  221. package/package.json +22 -5
  222. package/templates/AGENTS.md +1 -1
  223. package/templates/motion/background.ts +17 -0
  224. package/templates/motion/context-menu.ts +63 -0
  225. package/templates/motion/dock.ts +327 -0
  226. package/templates/motion/modal.ts +79 -0
  227. package/templates/motion/notification.ts +27 -0
  228. package/templates/motion/tokens.ts +47 -0
  229. package/templates/tsconfig.json +7 -0
  230. package/dist/modules/ambient/color.d.ts +0 -21
  231. package/dist/modules/ambient/color.d.ts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/modules/ambient/server/address.ts","../../../../src/modules/ambient/server/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// Which hosts and addresses the server entry refuses to fetch from: anything\n// that is not plainly on the public internet.\n\nconst PRIVATE_NAMES = /(^|\\.)(localhost|local|internal|intranet|lan|home\\.arpa|localdomain)$/;\n\n/** Lower-cased, without the trailing dot(s) and IPv6 brackets. */\nexport function normalizeHost(hostname: string): string {\n return hostname.toLowerCase().replace(/\\.+$/, \"\").replace(/^\\[|\\]$/g, \"\");\n}\n\nfunction parseIPv4(value: string): number[] | null {\n const parts = value.split(\".\");\n if (parts.length !== 4) return null;\n const bytes = parts.map((part) => (/^\\d{1,3}$/.test(part) ? Number(part) : NaN));\n return bytes.every((byte) => byte >= 0 && byte <= 255) ? bytes : null;\n}\n\nfunction isPrivateIPv4([a, b, c]: number[]): boolean {\n return (\n a === 0 || // \"this network\"\n a === 10 ||\n a === 127 ||\n (a === 100 && b >= 64 && b <= 127) || // CGNAT\n (a === 169 && b === 254) || // link-local, cloud metadata\n (a === 172 && b >= 16 && b <= 31) ||\n (a === 192 && b === 168) ||\n (a === 192 && b === 0 && c === 0) || // IETF protocol assignments\n (a === 198 && (b === 18 || b === 19)) || // benchmarking\n a >= 224 // multicast, reserved, broadcast\n );\n}\n\n/** Eight 16-bit groups, or `null` when `value` is not an IPv6 address. */\nfunction parseIPv6(value: string): number[] | null {\n let text = value.split(\"%\")[0]; // zone id\n const tail = text.match(/^(.*:)(\\d+\\.\\d+\\.\\d+\\.\\d+)$/);\n if (tail) {\n const v4 = parseIPv4(tail[2]);\n if (!v4) return null;\n text = `${tail[1]}${((v4[0] << 8) | v4[1]).toString(16)}:${((v4[2] << 8) | v4[3]).toString(16)}`;\n }\n const halves = text.split(\"::\");\n if (halves.length > 2) return null;\n const read = (part: string) => (part ? part.split(\":\") : []);\n const head = read(halves[0]);\n const rest = halves.length === 2 ? read(halves[1]) : [];\n const missing = 8 - head.length - rest.length;\n if (halves.length === 1 ? missing !== 0 : missing < 1) return null;\n const groups = [...head, ...Array(halves.length === 2 ? missing : 0).fill(\"0\"), ...rest];\n const words = groups.map((group) => (/^[0-9a-f]{1,4}$/.test(group) ? parseInt(group, 16) : NaN));\n return words.length === 8 && words.every((word) => word >= 0) ? words : null;\n}\n\nfunction isPrivateIPv6(words: number[]): boolean {\n const [w0, w1, w2, w3, w4, w5, w6, w7] = words;\n const embedded = () => [w6 >> 8, w6 & 255, w7 >> 8, w7 & 255];\n if (words.slice(0, 7).every((word) => word === 0)) return w7 <= 1; // :: and ::1\n // IPv4-mapped (::ffff:a.b.c.d), IPv4-compatible (::a.b.c.d), NAT64 (64:ff9b::a.b.c.d)\n if (w0 === 0 && w1 === 0 && w2 === 0 && w3 === 0 && w4 === 0 && (w5 === 0xffff || w5 === 0)) {\n return isPrivateIPv4(embedded());\n }\n if (w0 === 0x64 && w1 === 0xff9b) return isPrivateIPv4(embedded());\n if (w0 === 0x2002) return isPrivateIPv4([w1 >> 8, w1 & 255, w2 >> 8, w2 & 255]); // 6to4\n return (\n (w0 & 0xfe00) === 0xfc00 || // unique local\n (w0 & 0xffc0) === 0xfe80 || // link-local\n (w0 & 0xff00) === 0xff00 || // multicast\n (w0 === 0x2001 && w1 === 0xdb8) // documentation\n );\n}\n\n/** `true` for loopback, private, link-local, CGNAT, multicast and reserved IPs. */\nexport function isPrivateAddress(address: string): boolean {\n const host = normalizeHost(address);\n const v4 = parseIPv4(host);\n if (v4) return isPrivateIPv4(v4);\n const v6 = parseIPv6(host);\n return v6 ? isPrivateIPv6(v6) : false;\n}\n\nexport const isIpLiteral = (hostname: string) => {\n const host = normalizeHost(hostname);\n return parseIPv4(host) !== null || parseIPv6(host) !== null;\n};\n\n/** A host name that only means something on a private network. */\nexport function isPrivateHostname(hostname: string): boolean {\n const host = normalizeHost(hostname);\n if (!host) return true;\n if (isIpLiteral(host)) return isPrivateAddress(host);\n return PRIVATE_NAMES.test(host) || !host.includes(\".\");\n}\n","import { analyzeAmbientPixels } from \"../analyze\";\nimport { isIpLiteral, isPrivateAddress, isPrivateHostname, normalizeHost } from \"./address\";\nimport { resolveAnalysis } from \"../settings\";\nimport type {\n AmbientAnalysisOptions,\n AmbientPalette,\n AmbientPixels,\n} from \"../types\";\n\n// `@omerdlw/base-framework/ambient/server`: palettes computed in Node (RSC,\n// route handlers, build scripts), to be cached and handed to the client as\n// `initialPalette`. Nothing here is client code.\n\nexport { analyzeAmbientPixels, findContentBounds, fitSample } from \"../analyze\";\nexport { isPrivateAddress, isPrivateHostname } from \"./address\";\nexport { configureAmbient, getAmbientSettings } from \"../settings\";\nexport {\n contrastRatio,\n formatOklch,\n maxChroma,\n onColorFor,\n srgbToOklab,\n toneOf,\n} from \"../oklab\";\nexport type * from \"../types\";\n\n/** Decodes image bytes into RGBA pixels no larger than `size` on the long side. */\nexport type AmbientDecoder = (\n bytes: Uint8Array,\n size: number,\n) => Promise<AmbientPixels>;\n\nexport interface AmbientServerOptions {\n analysis?: Partial<AmbientAnalysisOptions>;\n /** Which URLs may be fetched. Default: public http(s) hosts only. */\n allow?: (url: URL) => boolean;\n /** Keep results in an in-process cache (default `true`). */\n cache?: boolean;\n /** Default: `sharp` (loaded on first use; it ships with Next.js). */\n decode?: AmbientDecoder;\n fetch?: typeof fetch;\n /** Extra fetch options, e.g. `{ next: { revalidate: 86400 } }`. */\n init?: RequestInit;\n maxBytes?: number;\n /**\n * Resolves a host name to its IP addresses, checked before every request\n * (redirects included): a request whose host resolves to any loopback,\n * private, link-local or reserved address is refused. Default: `node:dns`.\n * `false` skips the check (only do that behind an `allow` list).\n */\n resolve?: ((hostname: string) => Promise<string[]>) | false;\n timeoutMs?: number;\n}\n\nconst MAX_BYTES = 12 * 1024 * 1024;\nconst TIMEOUT_MS = 8_000;\nconst CACHE_LIMIT = 500;\n\n/**\n * Public http(s) URLs only: no credentials, no localhost / private / link-local\n * names or IP literals (in any spelling the URL parser accepts). Host names\n * are also resolved and checked before fetching (`resolve`).\n */\nexport function isPublicImageUrl(url: URL): boolean {\n return (\n (url.protocol === \"https:\" || url.protocol === \"http:\") &&\n !url.username &&\n !url.password &&\n !isPrivateHostname(url.hostname)\n );\n}\n\nasync function lookupAll(hostname: string): Promise<string[]> {\n const { lookup } = await import(\"node:dns/promises\");\n return (await lookup(hostname, { all: true, verbatim: true })).map(\n (entry) => entry.address,\n );\n}\n\nasync function reachesOnlyPublic(\n url: URL,\n resolve: AmbientServerOptions[\"resolve\"],\n): Promise<boolean> {\n if (resolve === false) return true;\n const host = normalizeHost(url.hostname);\n try {\n const addresses = isIpLiteral(host) ? [host] : await (resolve ?? lookupAll)(host);\n return addresses.length > 0 && !addresses.some(isPrivateAddress);\n } catch {\n return false;\n }\n}\n\ninterface SharpLike {\n (input: Uint8Array, options?: Record<string, unknown>): SharpPipeline;\n}\ninterface SharpPipeline {\n ensureAlpha(): SharpPipeline;\n raw(): SharpPipeline;\n resize(width: number, height: number, options: Record<string, unknown>): SharpPipeline;\n rotate(): SharpPipeline;\n toBuffer(options: { resolveWithObject: true }): Promise<{\n data: Uint8Array;\n info: { height: number; width: number };\n }>;\n}\n\n/** Thrown (not swallowed) when no decoder is available: a setup error, not a bad image. */\nexport class AmbientDecoderMissingError extends Error {\n override name = \"AmbientDecoderMissingError\";\n}\n\nlet sharpModule: Promise<SharpLike> | null = null;\nconst SHARP = \"sharp\";\n\nfunction loadSharp(): Promise<SharpLike> {\n sharpModule ??= import(/* webpackIgnore: true */ /* turbopackIgnore: true */ SHARP)\n .then((mod: { default?: SharpLike }) => (mod.default ?? mod) as SharpLike)\n .catch((error: unknown) => {\n sharpModule = null;\n throw new AmbientDecoderMissingError(\n \"ambient/server: `sharp` is not installed. Install it or pass `decode`.\",\n { cause: error },\n );\n });\n return sharpModule;\n}\n\n/** The default decoder: `sharp`, resized inside libvips. */\nexport const sharpDecoder: AmbientDecoder = async (bytes, size) => {\n const sharp = await loadSharp();\n const { data, info } = await sharp(bytes, { failOn: \"none\" })\n .rotate()\n .resize(size, size, { fit: \"inside\", withoutEnlargement: true })\n .ensureAlpha()\n .raw()\n .toBuffer({ resolveWithObject: true });\n return { data, height: info.height, width: info.width };\n};\n\nasync function readLimited(response: Response, maxBytes: number): Promise<Uint8Array> {\n const declared = Number(response.headers.get(\"content-length\"));\n if (declared > maxBytes) throw new Error(\"ambient/server: image too large\");\n if (!response.body) return new Uint8Array(await response.arrayBuffer());\n\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let length = 0;\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n length += value.byteLength;\n if (length > maxBytes) {\n await reader.cancel();\n throw new Error(\"ambient/server: image too large\");\n }\n chunks.push(value);\n }\n const bytes = new Uint8Array(length);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return bytes;\n}\n\n/** The palette of image bytes (JPEG, PNG, WebP, AVIF… whatever the decoder reads). */\nexport async function extractAmbientPaletteFromBytes(\n bytes: Uint8Array,\n options: Pick<AmbientServerOptions, \"analysis\" | \"decode\"> = {},\n): Promise<AmbientPalette> {\n const analysis = resolveAnalysis(options.analysis);\n const pixels = await (options.decode ?? sharpDecoder)(bytes, analysis.sampleSize);\n return analyzeAmbientPixels(pixels, analysis);\n}\n\nconst cache = new Map<string, AmbientPalette>();\nconst inFlight = new Map<string, Promise<AmbientPalette | null>>();\n\nfunction remember(key: string, palette: AmbientPalette): void {\n cache.delete(key);\n while (cache.size >= CACHE_LIMIT) {\n const oldest = cache.keys().next().value;\n if (oldest === undefined) break;\n cache.delete(oldest);\n }\n cache.set(key, palette);\n}\n\nasync function fetchAndExtract(\n url: URL,\n options: AmbientServerOptions,\n): Promise<AmbientPalette | null> {\n const allow = options.allow ?? isPublicImageUrl;\n const doFetch = options.fetch ?? fetch;\n const signal = AbortSignal.timeout(options.timeoutMs ?? TIMEOUT_MS);\n\n let current = url;\n for (let hop = 0; hop <= 5; hop++) {\n if (!allow(current)) return null;\n // Checked on every hop. The fetch resolves the name again, so a host that\n // changes its answer in between (DNS rebinding) is only ruled out by an\n // `allow` list of hosts you trust.\n if (!(await reachesOnlyPublic(current, options.resolve))) return null;\n const response = await doFetch(current, {\n ...options.init,\n redirect: \"manual\",\n signal,\n });\n if (response.status >= 300 && response.status < 400) {\n const location = response.headers.get(\"location\");\n await response.body?.cancel();\n if (!location) return null;\n current = new URL(location, current);\n continue;\n }\n if (!response.ok) return null;\n const type = response.headers.get(\"content-type\") ?? \"\";\n if (type && !type.toLowerCase().startsWith(\"image/\")) return null;\n const bytes = await readLimited(response, options.maxBytes ?? MAX_BYTES);\n const palette = await extractAmbientPaletteFromBytes(bytes, options);\n return { ...palette, source: url.href };\n }\n return null;\n}\n\n/**\n * Fetches an image and returns its palette, or `null` when it cannot be\n * fetched or decoded. `source` is the URL, so a client theme given the same\n * image and this palette as `initialPalette` does not extract it again.\n *\n * Wrap it in the app's cache (`\"use cache\"`, `unstable_cache`…) to keep\n * palettes across requests; an in-process cache is kept as well.\n */\nexport async function extractAmbientPalette(\n src: string | URL,\n options: AmbientServerOptions = {},\n): Promise<AmbientPalette | null> {\n let url: URL;\n try {\n url = new URL(src);\n } catch {\n return null;\n }\n const useCache = options.cache !== false;\n const key = options.analysis\n ? `${url.href}#${JSON.stringify(options.analysis)}`\n : url.href;\n if (useCache) {\n const hit = cache.get(key);\n if (hit) return hit;\n const pending = inFlight.get(key);\n if (pending) return pending;\n }\n\n const task = fetchAndExtract(url, options).catch((error: unknown) => {\n if (error instanceof AmbientDecoderMissingError) throw error;\n return null;\n });\n if (!useCache) return task;\n\n const shared = task\n .then((palette) => {\n if (palette) remember(key, palette);\n return palette;\n })\n .finally(() => inFlight.delete(key));\n inFlight.set(key, shared);\n return shared;\n}\n"]}
@@ -0,0 +1,19 @@
1
+ import type { AmbientAnalysisOptions, AmbientCssVarNames, AmbientProxy, AmbientSettings, AmbientSettingsInput } from "./types";
2
+ export declare const AMBIENT_TONES: readonly [10, 15, 20, 30, 40, 50, 60, 70, 80, 90, 95];
3
+ export declare const AMBIENT_ROLES: readonly ["dominant", "vibrant", "muted", "accent"];
4
+ export declare const AMBIENT_REGIONS: readonly ["top", "bottom", "left", "right", "center"];
5
+ export declare const DEFAULT_ANALYSIS: Readonly<AmbientAnalysisOptions>;
6
+ export declare const DEFAULT_CSS_VAR_NAMES: Readonly<AmbientCssVarNames>;
7
+ export declare const DEFAULT_PROXY = "/api/ambient/proxy?url=";
8
+ export declare function getAmbientSettings(): AmbientSettings;
9
+ export declare function mergeAmbientSettings(base: AmbientSettings, input: AmbientSettingsInput): AmbientSettings;
10
+ /**
11
+ * Sets the proxy, CSS variable names, extraction strategy, worker and analysis
12
+ * defaults for every ambient theme. Returns a function that restores the
13
+ * previous settings.
14
+ */
15
+ export declare function configureAmbient(input: AmbientSettingsInput): () => void;
16
+ export declare function resolveAnalysis(overrides?: Partial<AmbientAnalysisOptions> | null): AmbientAnalysisOptions;
17
+ /** The URL to retry through, or `null` when no proxy applies. */
18
+ export declare function resolveProxyUrl(proxy: AmbientProxy, src: string): string | null;
19
+ //# sourceMappingURL=settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/modules/ambient/settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,oBAAoB,EAErB,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,aAAa,uDAEkB,CAAC;AAE7C,eAAO,MAAM,aAAa,qDAKf,CAAC;AAEZ,eAAO,MAAM,eAAe,uDAMjB,CAAC;AAEZ,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,sBAAsB,CAQ5D,CAAC;AAEH,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,kBAAkB,CAM7D,CAAC;AAEH,eAAO,MAAM,aAAa,4BAA4B,CAAC;AAmBvD,wBAAgB,kBAAkB,IAAI,eAAe,CAEpD;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,oBAAoB,GAC1B,eAAe,CASjB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,IAAI,CAOxE;AAED,wBAAgB,eAAe,CAC7B,SAAS,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,GAAG,IAAI,GACjD,sBAAsB,CAExB;AAED,iEAAiE;AACjE,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAO/E"}
@@ -1,19 +1,113 @@
1
1
  import type { Dispatch, ReactNode, RefObject, SetStateAction } from "react";
2
- import type { ModuleRuntime } from "@/kernel";
2
+ import type { ModuleRuntime } from "../../kernel";
3
3
  export type AmbientThemeSlot = "transition";
4
+ /** Tones of a ramp, as OKLCH lightness × 100. */
5
+ export type AmbientTone = 10 | 15 | 20 | 30 | 40 | 50 | 60 | 70 | 80 | 90 | 95;
6
+ export type AmbientRole = "dominant" | "vibrant" | "muted" | "accent";
7
+ export type AmbientRegion = "top" | "bottom" | "left" | "right" | "center";
8
+ export type AmbientRamp = Record<AmbientTone, string>;
9
+ export interface AmbientSwatch {
10
+ /** The role at a tone that works as a colour on its own (CSS `oklch()`). */
11
+ color: string;
12
+ /** Text colour on `color` that meets the configured contrast (4.5:1 by default). */
13
+ on: string;
14
+ l: number;
15
+ c: number;
16
+ h: number;
17
+ /** Share of the image this colour covers (0–1, centre-weighted). */
18
+ population: number;
19
+ /** `false` when the image had no such colour and the role was derived. */
20
+ fromImage: boolean;
21
+ /** The same hue from deep to pale, each tone at the chroma sRGB allows there. */
22
+ ramp: AmbientRamp;
23
+ }
24
+ export interface AmbientRegionColor {
25
+ color: string;
26
+ l: number;
27
+ c: number;
28
+ h: number;
29
+ /** How coloured the region is (0 neutral … 1 fully chromatic). */
30
+ strength: number;
31
+ }
4
32
  export interface AmbientPalette {
5
- black: string;
6
- primary: string;
33
+ /** The image the palette was made from. */
7
34
  source?: string | null;
35
+ /** `true` when the image has (almost) no colour; no hue was invented. */
36
+ neutral: boolean;
37
+ /** Deep background tone: the shadows' own hue, else the dominant's. */
38
+ shadow: string;
39
+ roles: Record<AmbientRole, AmbientSwatch>;
40
+ regions: Record<AmbientRegion, AmbientRegionColor>;
8
41
  }
9
42
  export interface OklchColor {
10
43
  c: number;
11
44
  h: number;
12
45
  l: number;
13
46
  }
47
+ export interface AmbientAnalysisOptions {
48
+ /** Long side of the sample in pixels. */
49
+ sampleSize: number;
50
+ /** k-means clusters (6–8 work best). */
51
+ clusters: number;
52
+ /** 0 = every pixel counts the same, 1 = the centre counts ~3× the corners. */
53
+ centerWeight: number;
54
+ /** Ignore black letterbox / pillarbox bars at the edges. */
55
+ letterbox: boolean;
56
+ /** Minimum hue distance (degrees) between `dominant` and `accent`. */
57
+ minHueDistance: number;
58
+ /** WCAG 2 contrast `on` colours must reach. */
59
+ minContrast: number;
60
+ /** Lightness of `shadow`. */
61
+ shadowLightness: number;
62
+ }
63
+ /** RGBA pixels, 4 bytes per pixel, row-major. */
64
+ export interface AmbientPixels {
65
+ data: ArrayLike<number>;
66
+ height: number;
67
+ width: number;
68
+ }
69
+ export type AmbientStrategy = "auto" | "worker" | "main" | "none";
70
+ /**
71
+ * Where to fetch an image from when the direct (CORS) request fails. A string
72
+ * is a prefix the encoded URL is appended to, or a template with `{url}`.
73
+ */
74
+ export type AmbientProxy = string | ((src: string) => string | null) | null;
75
+ export interface AmbientCssVarNames {
76
+ shadow: string | null;
77
+ /** Templates; `{role}`, `{tone}` and `{region}` are filled in. `null` turns a group off. */
78
+ role: string | null;
79
+ on: string | null;
80
+ tone: string | null;
81
+ region: string | null;
82
+ }
83
+ export interface AmbientCssVarConfig extends Partial<AmbientCssVarNames> {
84
+ /** Ramp tones written as variables; `false` writes none. */
85
+ tones?: readonly AmbientTone[] | false;
86
+ }
87
+ export interface AmbientSettings {
88
+ analysis: AmbientAnalysisOptions;
89
+ cacheLimit: number;
90
+ cssVars: AmbientCssVarNames & {
91
+ tones: readonly AmbientTone[] | false;
92
+ };
93
+ proxy: AmbientProxy;
94
+ strategy: AmbientStrategy;
95
+ /** Builds the extraction worker (see `serveAmbientWorker`). */
96
+ worker: (() => Worker) | null;
97
+ }
98
+ export interface AmbientSettingsInput {
99
+ analysis?: Partial<AmbientAnalysisOptions>;
100
+ cacheLimit?: number;
101
+ cssVars?: AmbientCssVarConfig;
102
+ proxy?: AmbientProxy;
103
+ strategy?: AmbientStrategy;
104
+ worker?: (() => Worker) | null;
105
+ }
14
106
  export interface AmbientExtractOptions {
15
- fallbackPalette?: AmbientPalette | null;
107
+ analysis?: Partial<AmbientAnalysisOptions>;
16
108
  initialPalette?: AmbientPalette | null;
109
+ proxy?: AmbientProxy;
110
+ strategy?: AmbientStrategy;
17
111
  }
18
112
  export type AmbientImageSource = string | {
19
113
  src: string;
@@ -21,11 +115,12 @@ export type AmbientImageSource = string | {
21
115
  export type AmbientTarget = string | HTMLElement | RefObject<HTMLElement | null> | null | undefined;
22
116
  export interface AmbientConfig {
23
117
  colors?: Record<string, string> | null;
118
+ /** Overrides the configured variable names for this theme. */
119
+ cssVars?: AmbientCssVarConfig | null;
24
120
  image?: AmbientImageSource;
25
121
  initialPalette?: AmbientPalette | null;
26
122
  options?: AmbientExtractOptions | null;
27
123
  scope?: AmbientTarget;
28
- tintGlobals?: boolean;
29
124
  transition?: boolean;
30
125
  }
31
126
  type AmbientProps = Record<string, unknown>;
@@ -56,17 +151,18 @@ export interface DefinedAmbient {
56
151
  }
57
152
  export interface AmbientContextValue {
58
153
  isExtracting: boolean;
59
- palette: AmbientPalette;
154
+ /** `null` until a palette exists; the app's own CSS defaults apply meanwhile. */
155
+ palette: AmbientPalette | null;
60
156
  setIsExtracting?: Dispatch<SetStateAction<boolean>>;
61
- setPalette?: Dispatch<SetStateAction<AmbientPalette>>;
157
+ setPalette?: Dispatch<SetStateAction<AmbientPalette | null>>;
62
158
  }
63
159
  export interface AmbientState {
64
160
  isExtracting: boolean;
65
- palette: AmbientPalette;
161
+ palette: AmbientPalette | null;
66
162
  }
67
163
  export type AmbientProviderValue = ModuleRuntime<AmbientState, {
68
164
  setIsExtracting: Dispatch<SetStateAction<boolean>>;
69
- setPalette: Dispatch<SetStateAction<AmbientPalette>>;
165
+ setPalette: Dispatch<SetStateAction<AmbientPalette | null>>;
70
166
  }>;
71
167
  export type AmbientPageConfig = boolean | string | AmbientConfig;
72
168
  export interface AmbientPageSlice {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/modules/ambient/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,MAAM,MAAM,gBAAgB,GAAG,YAAY,CAAC;AAE5C,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,qBAAqB;IACpC,eAAe,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IACxC,cAAc,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;CACxC;AAED,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,CAAC;AAE7E,MAAM,MAAM,aAAa,GACvB,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;AAE1E,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACvC,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,cAAc,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACvC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5C,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACtD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,kBAAkB,CAAC;IAC1B,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,OAAO,EAAE,qBAAqB,CAAC;IAC/B,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAChD,aAAa,EACb,QAAQ,GAAG,OAAO,CACnB;IACC,MAAM,CAAC,EACH,aAAa,CAAC,QAAQ,CAAC,GACvB,CAAC,CAAC,KAAK,EAAE,YAAY,KAAK,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;IACvD,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,kBAAkB,GAAG,CAAC,CAAC,KAAK,EAAE,YAAY,KAAK,kBAAkB,CAAC,CAAC;CAC5E;AAED,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,MAAM,EAAE,CACN,KAAK,CAAC,EAAE,YAAY,EACpB,SAAS,CAAC,EAAE,gBAAgB,KACzB,iBAAiB,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,YAAY,EAAE,SAAS,CAAC,EAAE,gBAAgB,KAAK,YAAY,CAAC;CAC3E;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,cAAc,CAAC;IACxB,eAAe,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACpD,UAAU,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,cAAc,CAAC;CACzB;AAED,MAAM,MAAM,oBAAoB,GAAG,aAAa,CAC9C,YAAY,EACZ;IACE,eAAe,EAAE,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACnD,UAAU,EAAE,QAAQ,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC;CACtD,CACF,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,MAAM,GAAG,aAAa,CAAC;AAEjE,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACvC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,cAAc,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;CACxC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/modules/ambient/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { type AmbientExtractRequest } from "../pipeline";
2
+ export declare const AMBIENT_WORKER_REQUEST = "ambient:extract";
3
+ export declare const AMBIENT_WORKER_RESPONSE = "ambient:palette";
4
+ export interface AmbientWorkerRequest extends AmbientExtractRequest {
5
+ id: number;
6
+ type: typeof AMBIENT_WORKER_REQUEST;
7
+ }
8
+ export interface AmbientWorkerScope {
9
+ addEventListener(type: "message", listener: (event: MessageEvent) => void): void;
10
+ postMessage(message: unknown): void;
11
+ removeEventListener(type: "message", listener: (event: MessageEvent) => void): void;
12
+ }
13
+ /** Answers extraction requests in a worker. Returns a function that stops it. */
14
+ export declare function serveAmbientWorker(scope?: AmbientWorkerScope): () => void;
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/modules/ambient/worker/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAC;AActE,eAAO,MAAM,sBAAsB,oBAAoB,CAAC;AACxD,eAAO,MAAM,uBAAuB,oBAAoB,CAAC;AAEzD,MAAM,WAAW,oBAAqB,SAAQ,qBAAqB;IACjE,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,sBAAsB,CAAC;CACrC;AAED,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI,CAAC;IACjF,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACpC,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI,CAAC;CACrF;AAED,iFAAiF;AACjF,wBAAgB,kBAAkB,CAChC,KAAK,GAAE,kBAAgE,GACtE,MAAM,IAAI,CAcZ"}
@@ -0,0 +1,114 @@
1
+ import { analyzeAmbientPixels, fitSample } from '../../../chunk-6SG7V77J.js';
2
+
3
+ // src/modules/ambient/pipeline.ts
4
+ async function fetchImageBlob(src, proxyUrl) {
5
+ if (typeof fetch !== "function") return null;
6
+ const read = async (url, init) => {
7
+ const response = await fetch(url, { ...init, mode: "cors" });
8
+ if (!response.ok) return null;
9
+ const blob = await response.blob();
10
+ return blob.type.startsWith("text/") ? null : blob;
11
+ };
12
+ try {
13
+ const blob = await read(src);
14
+ if (blob) return blob;
15
+ } catch {
16
+ if (isCrossOrigin(src)) {
17
+ try {
18
+ const blob = await read(src, { cache: "reload" });
19
+ if (blob) return blob;
20
+ } catch {
21
+ }
22
+ }
23
+ }
24
+ if (proxyUrl) {
25
+ try {
26
+ return await read(proxyUrl);
27
+ } catch {
28
+ }
29
+ }
30
+ return null;
31
+ }
32
+ function isCrossOrigin(url) {
33
+ try {
34
+ return new URL(url).origin !== globalThis.location?.origin;
35
+ } catch {
36
+ return false;
37
+ }
38
+ }
39
+ function createContext2D(width, height) {
40
+ if (typeof OffscreenCanvas === "function") {
41
+ return new OffscreenCanvas(width, height).getContext("2d", {
42
+ willReadFrequently: true
43
+ });
44
+ }
45
+ if (typeof document !== "undefined") {
46
+ const canvas = document.createElement("canvas");
47
+ canvas.width = width;
48
+ canvas.height = height;
49
+ return canvas.getContext("2d", { willReadFrequently: true });
50
+ }
51
+ return null;
52
+ }
53
+ function readPixels(image, sourceWidth, sourceHeight, size) {
54
+ const { height, width } = fitSample(sourceWidth, sourceHeight, size);
55
+ const context = createContext2D(width, height);
56
+ if (!context) return null;
57
+ context.drawImage(image, 0, 0, width, height);
58
+ return { data: context.getImageData(0, 0, width, height).data, height, width };
59
+ }
60
+ async function decodeBlob(blob, size) {
61
+ if (typeof createImageBitmap !== "function") return null;
62
+ let bitmap;
63
+ try {
64
+ bitmap = await createImageBitmap(blob, {
65
+ resizeQuality: "medium",
66
+ resizeWidth: size
67
+ });
68
+ } catch {
69
+ bitmap = await createImageBitmap(blob);
70
+ }
71
+ try {
72
+ return readPixels(bitmap, bitmap.width, bitmap.height, size);
73
+ } finally {
74
+ bitmap.close();
75
+ }
76
+ }
77
+ var canDecodeHere = () => typeof createImageBitmap === "function" && (typeof OffscreenCanvas === "function" || typeof document !== "undefined");
78
+ async function extractHere(request) {
79
+ if (!canDecodeHere()) return { supported: false };
80
+ const blob = await fetchImageBlob(request.src, request.proxyUrl);
81
+ if (!blob) return { palette: null, supported: true };
82
+ try {
83
+ const pixels = await decodeBlob(blob, request.analysis.sampleSize);
84
+ return {
85
+ palette: pixels ? analyzeAmbientPixels(pixels, request.analysis) : null,
86
+ supported: true
87
+ };
88
+ } catch {
89
+ return { palette: null, supported: true };
90
+ }
91
+ }
92
+
93
+ // src/modules/ambient/worker/index.ts
94
+ var AMBIENT_WORKER_REQUEST = "ambient:extract";
95
+ var AMBIENT_WORKER_RESPONSE = "ambient:palette";
96
+ function serveAmbientWorker(scope = globalThis) {
97
+ const onMessage = async (event) => {
98
+ const request = event.data;
99
+ if (request?.type !== AMBIENT_WORKER_REQUEST) return;
100
+ let result;
101
+ try {
102
+ result = await extractHere(request);
103
+ } catch {
104
+ result = { palette: null, supported: true };
105
+ }
106
+ scope.postMessage({ ...result, id: request.id, type: AMBIENT_WORKER_RESPONSE });
107
+ };
108
+ scope.addEventListener("message", onMessage);
109
+ return () => scope.removeEventListener("message", onMessage);
110
+ }
111
+
112
+ export { AMBIENT_WORKER_REQUEST, AMBIENT_WORKER_RESPONSE, serveAmbientWorker };
113
+ //# sourceMappingURL=index.js.map
114
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/modules/ambient/pipeline.ts","../../../../src/modules/ambient/worker/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { analyzeAmbientPixels, fitSample } from \"./analyze\";\nimport type {\n AmbientAnalysisOptions,\n AmbientPalette,\n AmbientPixels,\n} from \"./types\";\n\n// Fetch → decode → analyze, written against what both a window and a worker\n// have (fetch, createImageBitmap, OffscreenCanvas), so the same code runs in\n// either.\n\nexport interface AmbientExtractRequest {\n analysis: AmbientAnalysisOptions;\n /** Absolute URL of a proxy to retry through, if any. */\n proxyUrl: string | null;\n /** Absolute image URL. */\n src: string;\n}\n\nexport type AmbientExtractResult =\n | { palette: AmbientPalette | null; supported: true }\n | { supported: false };\n\ntype Context2D = OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D;\n\nexport async function fetchImageBlob(\n src: string,\n proxyUrl: string | null,\n): Promise<Blob | null> {\n if (typeof fetch !== \"function\") return null;\n\n const read = async (url: string, init?: RequestInit) => {\n const response = await fetch(url, { ...init, mode: \"cors\" });\n if (!response.ok) return null;\n const blob = await response.blob();\n // An HTML error page served with 200 is not an image.\n return blob.type.startsWith(\"text/\") ? null : blob;\n };\n\n // 1. The image itself: a CORS request for the URL the page already shows is\n // answered from the HTTP cache, so nothing is downloaded twice.\n try {\n const blob = await read(src);\n if (blob) return blob;\n } catch {\n // 2. Blocked. Some CDNs (TMDB's among them) send CORS headers only when\n // asked and do not `Vary: Origin`, so the copy an <img> cached has none.\n // Fetching past the cache gets one that has them, once.\n if (isCrossOrigin(src)) {\n try {\n const blob = await read(src, { cache: \"reload\" });\n if (blob) return blob;\n } catch {}\n }\n }\n\n // 3. Through the proxy.\n if (proxyUrl) {\n try {\n return await read(proxyUrl);\n } catch {}\n }\n return null;\n}\n\nfunction isCrossOrigin(url: string): boolean {\n try {\n return new URL(url).origin !== globalThis.location?.origin;\n } catch {\n return false;\n }\n}\n\nexport function createContext2D(width: number, height: number): Context2D | null {\n if (typeof OffscreenCanvas === \"function\") {\n return new OffscreenCanvas(width, height).getContext(\"2d\", {\n willReadFrequently: true,\n });\n }\n if (typeof document !== \"undefined\") {\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n return canvas.getContext(\"2d\", { willReadFrequently: true });\n }\n return null;\n}\n\nexport function readPixels(\n image: CanvasImageSource,\n sourceWidth: number,\n sourceHeight: number,\n size: number,\n): AmbientPixels | null {\n const { height, width } = fitSample(sourceWidth, sourceHeight, size);\n const context = createContext2D(width, height);\n if (!context) return null;\n context.drawImage(image, 0, 0, width, height);\n return { data: context.getImageData(0, 0, width, height).data, height, width };\n}\n\n/**\n * Decodes off the main thread: `createImageBitmap` decodes (and, where\n * supported, downscales) in the browser's image pipeline, so only a small\n * bitmap is ever drawn.\n */\nexport async function decodeBlob(\n blob: Blob,\n size: number,\n): Promise<AmbientPixels | null> {\n if (typeof createImageBitmap !== \"function\") return null;\n let bitmap: ImageBitmap;\n try {\n bitmap = await createImageBitmap(blob, {\n resizeQuality: \"medium\",\n resizeWidth: size,\n });\n } catch {\n bitmap = await createImageBitmap(blob);\n }\n try {\n return readPixels(bitmap, bitmap.width, bitmap.height, size);\n } finally {\n bitmap.close();\n }\n}\n\nexport const canDecodeHere = () =>\n typeof createImageBitmap === \"function\" &&\n (typeof OffscreenCanvas === \"function\" || typeof document !== \"undefined\");\n\nexport async function extractHere(\n request: AmbientExtractRequest,\n): Promise<AmbientExtractResult> {\n if (!canDecodeHere()) return { supported: false };\n const blob = await fetchImageBlob(request.src, request.proxyUrl);\n if (!blob) return { palette: null, supported: true };\n try {\n const pixels = await decodeBlob(blob, request.analysis.sampleSize);\n return {\n palette: pixels ? analyzeAmbientPixels(pixels, request.analysis) : null,\n supported: true,\n };\n } catch {\n return { palette: null, supported: true };\n }\n}\n","import { extractHere, type AmbientExtractRequest } from \"../pipeline\";\n\n// `@omerdlw/base-framework/ambient/worker`: runs extraction off the main thread.\n//\n// // ambient.worker.ts (in the app)\n// import { serveAmbientWorker } from \"@omerdlw/base-framework/ambient/worker\";\n// serveAmbientWorker();\n//\n// // once, on the client\n// configureAmbient({\n// worker: () =>\n// new Worker(new URL(\"./ambient.worker.ts\", import.meta.url), { type: \"module\" }),\n// });\n\nexport const AMBIENT_WORKER_REQUEST = \"ambient:extract\";\nexport const AMBIENT_WORKER_RESPONSE = \"ambient:palette\";\n\nexport interface AmbientWorkerRequest extends AmbientExtractRequest {\n id: number;\n type: typeof AMBIENT_WORKER_REQUEST;\n}\n\nexport interface AmbientWorkerScope {\n addEventListener(type: \"message\", listener: (event: MessageEvent) => void): void;\n postMessage(message: unknown): void;\n removeEventListener(type: \"message\", listener: (event: MessageEvent) => void): void;\n}\n\n/** Answers extraction requests in a worker. Returns a function that stops it. */\nexport function serveAmbientWorker(\n scope: AmbientWorkerScope = globalThis as unknown as AmbientWorkerScope,\n): () => void {\n const onMessage = async (event: MessageEvent) => {\n const request = event.data as AmbientWorkerRequest | null;\n if (request?.type !== AMBIENT_WORKER_REQUEST) return;\n let result: Awaited<ReturnType<typeof extractHere>>;\n try {\n result = await extractHere(request);\n } catch {\n result = { palette: null, supported: true };\n }\n scope.postMessage({ ...result, id: request.id, type: AMBIENT_WORKER_RESPONSE });\n };\n scope.addEventListener(\"message\", onMessage);\n return () => scope.removeEventListener(\"message\", onMessage);\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { type BackgroundThemeSlot } from "./types";
2
- export declare const backgroundTheme: import("@/theme").ThemeSpec<BackgroundThemeSlot>;
1
+ import { type BackgroundMotion, type BackgroundThemeSlot } from "./types";
2
+ export declare const backgroundTheme: import("../../theme").ThemeSpec<BackgroundThemeSlot, BackgroundMotion>;
3
3
  export declare const BACKGROUND_REGISTRY_KEY = "page-background";
4
4
  export declare const BACKGROUND_MEDIA_ID = "background";
5
5
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/modules/background/constants.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAGnD,eAAO,MAAM,eAAe,kDACwB,CAAC;AAErD,eAAO,MAAM,uBAAuB,oBAAoB,CAAC;AACzD,eAAO,MAAM,mBAAmB,eAAe,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/modules/background/constants.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE1E,eAAO,MAAM,eAAe,oEAGb,CAAC;AAEhB,eAAO,MAAM,uBAAuB,oBAAoB,CAAC;AACzD,eAAO,MAAM,mBAAmB,eAAe,CAAC"}
@@ -1,4 +1,4 @@
1
- import { type RegistryMetadata } from "@/kernel";
1
+ import { type RegistryMetadata } from "../../kernel";
2
2
  import type { BackgroundActions, BackgroundPageConfig, BackgroundStateComputed } from "./types";
3
3
  export declare function useBackgroundRegistration(config: BackgroundPageConfig | null | undefined, options?: RegistryMetadata & {
4
4
  enabled?: boolean;