@omerdlw/base-framework 1.0.6 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/dist/atoms/index.js +1 -103
  2. package/dist/atoms/index.js.map +1 -1
  3. package/dist/chunk-3BUP64Q6.js +105 -0
  4. package/dist/chunk-3BUP64Q6.js.map +1 -0
  5. package/dist/chunk-3MSK4XGK.js +9888 -0
  6. package/dist/chunk-3MSK4XGK.js.map +1 -0
  7. package/dist/chunk-4GMQKD6F.js +353 -0
  8. package/dist/chunk-4GMQKD6F.js.map +1 -0
  9. package/dist/chunk-65ZB4QTQ.js +888 -0
  10. package/dist/chunk-65ZB4QTQ.js.map +1 -0
  11. package/dist/chunk-6SG7V77J.js +577 -0
  12. package/dist/chunk-6SG7V77J.js.map +1 -0
  13. package/dist/chunk-7HQMXTNP.js +419 -0
  14. package/dist/chunk-7HQMXTNP.js.map +1 -0
  15. package/dist/chunk-7TAVYJ3A.js +371 -0
  16. package/dist/chunk-7TAVYJ3A.js.map +1 -0
  17. package/dist/chunk-AQ4BNXA2.js +349 -0
  18. package/dist/chunk-AQ4BNXA2.js.map +1 -0
  19. package/dist/chunk-CGHZSSFR.js +2166 -0
  20. package/dist/chunk-CGHZSSFR.js.map +1 -0
  21. package/dist/chunk-DGCQWQLZ.js +61 -0
  22. package/dist/chunk-DGCQWQLZ.js.map +1 -0
  23. package/dist/chunk-FIMPHODX.js +67 -0
  24. package/dist/chunk-FIMPHODX.js.map +1 -0
  25. package/dist/chunk-GF7TUX5I.js +1889 -0
  26. package/dist/chunk-GF7TUX5I.js.map +1 -0
  27. package/dist/chunk-JELG4JLT.js +454 -0
  28. package/dist/chunk-JELG4JLT.js.map +1 -0
  29. package/dist/chunk-K676GL7Z.js +51 -0
  30. package/dist/chunk-K676GL7Z.js.map +1 -0
  31. package/dist/chunk-KKQT46TP.js +26 -0
  32. package/dist/chunk-KKQT46TP.js.map +1 -0
  33. package/dist/chunk-QI3ALLIB.js +38 -0
  34. package/dist/chunk-QI3ALLIB.js.map +1 -0
  35. package/dist/chunk-QXR55VVS.js +1139 -0
  36. package/dist/chunk-QXR55VVS.js.map +1 -0
  37. package/dist/chunk-R2YGFJDJ.js +408 -0
  38. package/dist/chunk-R2YGFJDJ.js.map +1 -0
  39. package/dist/chunk-RFZQWLC5.js +27 -0
  40. package/dist/chunk-RFZQWLC5.js.map +1 -0
  41. package/dist/chunk-SYAVGTOX.js +521 -0
  42. package/dist/chunk-SYAVGTOX.js.map +1 -0
  43. package/dist/chunk-TV3WEF5G.js +784 -0
  44. package/dist/chunk-TV3WEF5G.js.map +1 -0
  45. package/dist/chunk-XASQT4CQ.js +280 -0
  46. package/dist/chunk-XASQT4CQ.js.map +1 -0
  47. package/dist/error/index.js +5 -682
  48. package/dist/error/index.js.map +1 -1
  49. package/dist/error/reporter.d.ts.map +1 -1
  50. package/dist/error/theme.d.ts +1 -1
  51. package/dist/error/theme.d.ts.map +1 -1
  52. package/dist/events.js +1 -7
  53. package/dist/events.js.map +1 -1
  54. package/dist/hooks/index.js +1 -358
  55. package/dist/hooks/index.js.map +1 -1
  56. package/dist/hooks/use-global-event.d.ts +1 -1
  57. package/dist/index.js +18 -20029
  58. package/dist/index.js.map +1 -1
  59. package/dist/kernel/index.js +2 -2035
  60. package/dist/kernel/index.js.map +1 -1
  61. package/dist/kernel/types.d.ts +1 -1
  62. package/dist/modules/ambient/analyze.d.ts +46 -0
  63. package/dist/modules/ambient/analyze.d.ts.map +1 -0
  64. package/dist/modules/ambient/constants.d.ts +1 -5
  65. package/dist/modules/ambient/constants.d.ts.map +1 -1
  66. package/dist/modules/ambient/context.d.ts.map +1 -1
  67. package/dist/modules/ambient/dom.d.ts +11 -12
  68. package/dist/modules/ambient/dom.d.ts.map +1 -1
  69. package/dist/modules/ambient/extractor.d.ts +10 -10
  70. package/dist/modules/ambient/extractor.d.ts.map +1 -1
  71. package/dist/modules/ambient/hooks.d.ts +1 -1
  72. package/dist/modules/ambient/hooks.d.ts.map +1 -1
  73. package/dist/modules/ambient/index.d.ts +6 -4
  74. package/dist/modules/ambient/index.d.ts.map +1 -1
  75. package/dist/modules/ambient/index.js +7 -762
  76. package/dist/modules/ambient/index.js.map +1 -1
  77. package/dist/modules/ambient/module.d.ts +1 -1
  78. package/dist/modules/ambient/module.d.ts.map +1 -1
  79. package/dist/modules/ambient/oklab.d.ts +36 -0
  80. package/dist/modules/ambient/oklab.d.ts.map +1 -0
  81. package/dist/modules/ambient/pipeline.d.ts +28 -0
  82. package/dist/modules/ambient/pipeline.d.ts.map +1 -0
  83. package/dist/modules/ambient/quantize.d.ts +22 -0
  84. package/dist/modules/ambient/quantize.d.ts.map +1 -0
  85. package/dist/modules/ambient/server/address.d.ts +8 -0
  86. package/dist/modules/ambient/server/address.d.ts.map +1 -0
  87. package/dist/modules/ambient/server/index.d.ts +53 -0
  88. package/dist/modules/ambient/server/index.d.ts.map +1 -0
  89. package/dist/modules/ambient/server/index.js +221 -0
  90. package/dist/modules/ambient/server/index.js.map +1 -0
  91. package/dist/modules/ambient/settings.d.ts +19 -0
  92. package/dist/modules/ambient/settings.d.ts.map +1 -0
  93. package/dist/modules/ambient/types.d.ts +105 -9
  94. package/dist/modules/ambient/types.d.ts.map +1 -1
  95. package/dist/modules/ambient/worker/index.d.ts +15 -0
  96. package/dist/modules/ambient/worker/index.d.ts.map +1 -0
  97. package/dist/modules/ambient/worker/index.js +114 -0
  98. package/dist/modules/ambient/worker/index.js.map +1 -0
  99. package/dist/modules/background/constants.d.ts +2 -2
  100. package/dist/modules/background/constants.d.ts.map +1 -1
  101. package/dist/modules/background/hooks.d.ts +1 -1
  102. package/dist/modules/background/index.js +6 -3078
  103. package/dist/modules/background/index.js.map +1 -1
  104. package/dist/modules/background/motion.d.ts +9 -7
  105. package/dist/modules/background/motion.d.ts.map +1 -1
  106. package/dist/modules/background/overlay.d.ts +3 -8
  107. package/dist/modules/background/overlay.d.ts.map +1 -1
  108. package/dist/modules/background/types.d.ts +16 -2
  109. package/dist/modules/background/types.d.ts.map +1 -1
  110. package/dist/modules/context-menu/constants.d.ts +2 -2
  111. package/dist/modules/context-menu/constants.d.ts.map +1 -1
  112. package/dist/modules/context-menu/hooks.d.ts +1 -1
  113. package/dist/modules/context-menu/index.js +10 -1896
  114. package/dist/modules/context-menu/index.js.map +1 -1
  115. package/dist/modules/context-menu/motion.d.ts +1 -8
  116. package/dist/modules/context-menu/motion.d.ts.map +1 -1
  117. package/dist/modules/context-menu/overlay.d.ts.map +1 -1
  118. package/dist/modules/context-menu/types.d.ts +16 -2
  119. package/dist/modules/context-menu/types.d.ts.map +1 -1
  120. package/dist/modules/controls/constants.d.ts +1 -1
  121. package/dist/modules/controls/constants.d.ts.map +1 -1
  122. package/dist/modules/controls/entries.d.ts +1 -1
  123. package/dist/modules/controls/hooks.d.ts +1 -1
  124. package/dist/modules/controls/index.js +4 -1110
  125. package/dist/modules/controls/index.js.map +1 -1
  126. package/dist/modules/controls/overlay.d.ts +1 -1
  127. package/dist/modules/controls/types.d.ts +2 -2
  128. package/dist/modules/dock/cards.d.ts +708 -24
  129. package/dist/modules/dock/cards.d.ts.map +1 -1
  130. package/dist/modules/dock/constants.d.ts +2 -2
  131. package/dist/modules/dock/constants.d.ts.map +1 -1
  132. package/dist/modules/dock/helpers.d.ts +2 -2
  133. package/dist/modules/dock/hooks.d.ts +2 -2
  134. package/dist/modules/dock/index.d.ts +1 -1
  135. package/dist/modules/dock/index.d.ts.map +1 -1
  136. package/dist/modules/dock/index.js +9 -12132
  137. package/dist/modules/dock/index.js.map +1 -1
  138. package/dist/modules/dock/module.d.ts +1 -1
  139. package/dist/modules/dock/motion.d.ts +41 -915
  140. package/dist/modules/dock/motion.d.ts.map +1 -1
  141. package/dist/modules/dock/overlay.d.ts.map +1 -1
  142. package/dist/modules/dock/runtime/dock.d.ts +1 -23
  143. package/dist/modules/dock/runtime/dock.d.ts.map +1 -1
  144. package/dist/modules/dock/styles.d.ts +4 -4
  145. package/dist/modules/dock/surface/hooks.d.ts +5 -20
  146. package/dist/modules/dock/surface/hooks.d.ts.map +1 -1
  147. package/dist/modules/dock/surface/machine.d.ts +4 -3
  148. package/dist/modules/dock/surface/machine.d.ts.map +1 -1
  149. package/dist/modules/dock/surface/stack.d.ts.map +1 -1
  150. package/dist/modules/dock/types.d.ts +158 -3
  151. package/dist/modules/dock/types.d.ts.map +1 -1
  152. package/dist/modules/index.js +16 -17883
  153. package/dist/modules/index.js.map +1 -1
  154. package/dist/modules/loading/constants.d.ts +1 -1
  155. package/dist/modules/loading/constants.d.ts.map +1 -1
  156. package/dist/modules/loading/context.d.ts +1 -1
  157. package/dist/modules/loading/hooks.d.ts +1 -1
  158. package/dist/modules/loading/index.js +5 -1153
  159. package/dist/modules/loading/index.js.map +1 -1
  160. package/dist/modules/loading/types.d.ts +2 -2
  161. package/dist/modules/media/context.d.ts +1 -1
  162. package/dist/modules/media/index.js +3 -570
  163. package/dist/modules/media/index.js.map +1 -1
  164. package/dist/modules/media/types.d.ts +2 -2
  165. package/dist/modules/modal/constants.d.ts +2 -2
  166. package/dist/modules/modal/constants.d.ts.map +1 -1
  167. package/dist/modules/modal/context.d.ts +1 -1
  168. package/dist/modules/modal/hooks.d.ts +3 -3
  169. package/dist/modules/modal/index.js +8 -2355
  170. package/dist/modules/modal/index.js.map +1 -1
  171. package/dist/modules/modal/motion.d.ts +3 -8
  172. package/dist/modules/modal/motion.d.ts.map +1 -1
  173. package/dist/modules/modal/overlay.d.ts.map +1 -1
  174. package/dist/modules/modal/types.d.ts +21 -0
  175. package/dist/modules/modal/types.d.ts.map +1 -1
  176. package/dist/modules/notification/constants.d.ts +2 -2
  177. package/dist/modules/notification/constants.d.ts.map +1 -1
  178. package/dist/modules/notification/context.d.ts +1 -1
  179. package/dist/modules/notification/hooks.d.ts +1 -1
  180. package/dist/modules/notification/index.js +4 -828
  181. package/dist/modules/notification/index.js.map +1 -1
  182. package/dist/modules/notification/motion.d.ts +1 -7
  183. package/dist/modules/notification/motion.d.ts.map +1 -1
  184. package/dist/modules/notification/overlay.d.ts.map +1 -1
  185. package/dist/modules/notification/types.d.ts +9 -1
  186. package/dist/modules/notification/types.d.ts.map +1 -1
  187. package/dist/overlay-TZ6L52A5.js +9 -0
  188. package/dist/overlay-TZ6L52A5.js.map +1 -0
  189. package/dist/provider.d.ts +1 -1
  190. package/dist/provider.d.ts.map +1 -1
  191. package/dist/provider.js +6 -1968
  192. package/dist/provider.js.map +1 -1
  193. package/dist/result.js +2 -63
  194. package/dist/result.js.map +1 -1
  195. package/dist/theme.d.ts +45 -8
  196. package/dist/theme.d.ts.map +1 -1
  197. package/dist/theme.js +3 -41
  198. package/dist/theme.js.map +1 -1
  199. package/dist/tokens/index.d.ts +1 -0
  200. package/dist/tokens/index.d.ts.map +1 -1
  201. package/dist/tokens/index.js +126 -155
  202. package/dist/tokens/index.js.map +1 -1
  203. package/dist/tokens/motion-config.d.ts +44 -0
  204. package/dist/tokens/motion-config.d.ts.map +1 -0
  205. package/dist/tokens/motion.d.ts +23 -174
  206. package/dist/tokens/motion.d.ts.map +1 -1
  207. package/dist/utils/index.js +4 -82
  208. package/dist/utils/index.js.map +1 -1
  209. package/dist/utils/report.d.ts.map +1 -1
  210. package/docs/README.md +1 -0
  211. package/docs/architecture-and-rules.md +4 -3
  212. package/docs/core-engine.md +7 -10
  213. package/docs/getting-started.md +4 -2
  214. package/docs/modules/ambient.md +194 -80
  215. package/docs/modules/background.md +3 -3
  216. package/docs/modules/context-menu.md +2 -2
  217. package/docs/modules/dock.md +8 -5
  218. package/docs/modules/modal.md +2 -2
  219. package/docs/modules/notification.md +2 -2
  220. package/docs/theming.md +81 -9
  221. package/package.json +22 -5
  222. package/templates/AGENTS.md +1 -1
  223. package/templates/motion/background.ts +17 -0
  224. package/templates/motion/context-menu.ts +63 -0
  225. package/templates/motion/dock.ts +327 -0
  226. package/templates/motion/modal.ts +79 -0
  227. package/templates/motion/notification.ts +27 -0
  228. package/templates/motion/tokens.ts +47 -0
  229. package/templates/tsconfig.json +7 -0
  230. package/dist/modules/ambient/color.d.ts +0 -21
  231. package/dist/modules/ambient/color.d.ts.map +0 -1
@@ -1,573 +1,6 @@
1
1
  "use client";
2
- import { createContext, useState, useRef, useMemo, useEffect, useContext, useId, useCallback, use, useSyncExternalStore } from 'react';
3
- import { jsx } from 'react/jsx-runtime';
4
-
5
- function getOrCreateGlobalContext(name, defaultValue) {
6
- const sym = /* @__PURE__ */ Symbol.for(`@omerdlw/base-framework/context/${name}`);
7
- const store = globalThis;
8
- if (!store[sym]) {
9
- store[sym] = createContext(defaultValue);
10
- }
11
- return store[sym];
12
- }
13
-
14
- // src/utils/object.ts
15
- function shallowEqual(a, b) {
16
- if (Object.is(a, b)) return true;
17
- if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) {
18
- return false;
19
- }
20
- const keysA = Object.keys(a);
21
- const keysB = Object.keys(b);
22
- if (keysA.length !== keysB.length) return false;
23
- for (const key of keysA) {
24
- if (!Object.prototype.hasOwnProperty.call(b, key) || !Object.is(
25
- a[key],
26
- b[key]
27
- )) {
28
- return false;
29
- }
30
- }
31
- return true;
32
- }
33
- function report(scope, error, level = "error") {
34
- if (process.env.NODE_ENV === "production" && typeof window !== "undefined") {
35
- return;
36
- }
37
- console[level](`[${scope}]`, error);
38
- }
39
-
40
- // src/utils/store.ts
41
- function freezeStoreSnapshot(state) {
42
- if (process.env.NODE_ENV === "production" || !state || typeof state !== "object") {
43
- return state;
44
- }
45
- const seen = /* @__PURE__ */ new WeakSet();
46
- const freeze = (value) => {
47
- if (seen.has(value) || Object.isFrozen(value)) return;
48
- seen.add(value);
49
- const prototype = Object.getPrototypeOf(value);
50
- if (Array.isArray(value) || prototype === Object.prototype || prototype === null) {
51
- for (const key of Reflect.ownKeys(value)) {
52
- const descriptor = Object.getOwnPropertyDescriptor(value, key);
53
- if (descriptor && "value" in descriptor && descriptor.value !== null) {
54
- if (typeof descriptor.value === "object") freeze(descriptor.value);
55
- }
56
- }
57
- }
58
- Object.freeze(value);
59
- };
60
- freeze(state);
61
- return state;
62
- }
63
- function createStore(initialState, { freezeSnapshots = true } = {}) {
64
- const listeners = /* @__PURE__ */ new Set();
65
- const prepare = freezeSnapshots ? freezeStoreSnapshot : (state) => state;
66
- let snapshot = prepare(initialState);
67
- const publish = (nextStateOrUpdater) => {
68
- const nextState = typeof nextStateOrUpdater === "function" ? nextStateOrUpdater(snapshot) : nextStateOrUpdater;
69
- if (Object.is(snapshot, nextState)) return false;
70
- snapshot = prepare(nextState);
71
- for (const listener of listeners) {
72
- try {
73
- listener();
74
- } catch (error) {
75
- report("CoreStore subscriber", error, "warn");
76
- }
77
- }
78
- return true;
79
- };
80
- const setState = (updater) => {
81
- if (typeof updater === "function") {
82
- return publish(updater);
83
- }
84
- if (snapshot && typeof snapshot === "object" && updater && typeof updater === "object") {
85
- return publish({ ...snapshot, ...updater });
86
- }
87
- return publish(updater);
88
- };
89
- return Object.freeze({
90
- getSnapshot() {
91
- return snapshot;
92
- },
93
- publish,
94
- setState,
95
- subscribe(listener) {
96
- if (typeof listener !== "function") return () => {
97
- };
98
- listeners.add(listener);
99
- return () => listeners.delete(listener);
100
- }
101
- });
102
- }
103
- function useRequiredContext(context, hookName, providerName) {
104
- const value = use(context);
105
- if (value === null) {
106
- throw new Error(`${hookName} must be used within ${providerName}`);
107
- }
108
- return value;
109
- }
110
- function useStore(store, selector = (state) => state, isEqual = Object.is) {
111
- const cacheRef = useRef({
112
- isEqual: null,
113
- selected: void 0,
114
- selector: null,
115
- snapshot: null
116
- });
117
- const getSelectedSnapshot = useCallback(() => {
118
- const snapshot = store.getSnapshot();
119
- const cache = cacheRef.current;
120
- if (cache.snapshot === snapshot && cache.selector === selector && cache.isEqual === isEqual) {
121
- return cache.selected;
122
- }
123
- const selected = selector(snapshot);
124
- if (cache.snapshot !== null && cache.isEqual === isEqual && isEqual(cache.selected, selected)) {
125
- cache.snapshot = snapshot;
126
- cache.selector = selector;
127
- return cache.selected;
128
- }
129
- cacheRef.current = {
130
- isEqual,
131
- selected,
132
- selector,
133
- snapshot
134
- };
135
- return selected;
136
- }, [isEqual, selector, store]);
137
- return useSyncExternalStore(
138
- store.subscribe,
139
- getSelectedSnapshot,
140
- getSelectedSnapshot
141
- );
142
- }
143
- var RegistryContext = getOrCreateGlobalContext(
144
- "RegistryContext",
145
- null
146
- );
147
- function useRegistrySubscription() {
148
- return useRequiredContext(
149
- RegistryContext,
150
- "useRegistrySubscription",
151
- "RegistryProvider"
152
- ).subscription;
153
- }
154
- function useRegistryValue(type, key) {
155
- const { getSnapshot, subscribe } = useRegistrySubscription();
156
- const subscribeToKey = useCallback(
157
- (listener) => subscribe(type, key, listener),
158
- [key, subscribe, type]
159
- );
160
- const getValue = useCallback(
161
- () => getSnapshot(type, key),
162
- [getSnapshot, key, type]
163
- );
164
- return useSyncExternalStore(subscribeToKey, getValue, getValue);
165
- }
166
- function defineModule(coreModule) {
167
- return Object.freeze({ ...coreModule });
168
- }
169
- createStore(void 0);
170
-
171
- // src/modules/media/constants.ts
172
- var DEFAULT_MEDIA_STATE = Object.freeze({
173
- audibleElement: null,
174
- element: null,
175
- hasMedia: false,
176
- isPlaying: false,
177
- kind: null,
178
- loop: false,
179
- sourceId: null
180
- });
181
- var INERT_MEDIA_ACTIONS = Object.freeze({
182
- removeSource: () => {
183
- },
184
- setMuted: () => {
185
- },
186
- toggle: () => {
187
- },
188
- toggleLoop: () => {
189
- },
190
- upsertSource: () => {
191
- }
192
- });
193
- var MEDIA_SYNC_DRIFT_SECONDS = 0.3;
194
- var MEDIA_REGISTRY_KEY = "page-media";
195
- var PAGE_MEDIA_ID = "page";
196
-
197
- // src/modules/media/playback.ts
198
- var noop = () => {
199
- };
200
- function toggleElement(element) {
201
- if (!element) return;
202
- if (element.paused || element.ended) {
203
- void Promise.resolve(element.play()).catch(noop);
204
- } else {
205
- element.pause();
206
- }
207
- }
208
- function safePlay(element) {
209
- try {
210
- void Promise.resolve(element.play()).catch(noop);
211
- } catch {
212
- }
213
- }
214
- function sameElements(a, b) {
215
- return a.length === b.length && a.every((element, index) => element === b[index]);
216
- }
217
- function bindFollowers(transport, followers) {
218
- const ownLoops = followers.map((follower) => follower.loop);
219
- const align = (hard) => {
220
- const time = Number(transport.currentTime) || 0;
221
- for (const follower of followers) {
222
- follower.loop = false;
223
- if (follower.playbackRate !== transport.playbackRate) {
224
- follower.playbackRate = transport.playbackRate;
225
- }
226
- const drift = Math.abs((Number(follower.currentTime) || 0) - time);
227
- if (hard || drift > MEDIA_SYNC_DRIFT_SECONDS) follower.currentTime = time;
228
- }
229
- };
230
- const play = () => {
231
- align(false);
232
- followers.forEach(safePlay);
233
- };
234
- const pause = () => followers.forEach((follower) => follower.pause());
235
- const hardAlign = () => align(true);
236
- const softAlign = () => align(false);
237
- const listeners = [
238
- ["play", play],
239
- ["playing", play],
240
- ["pause", pause],
241
- ["waiting", pause],
242
- ["ended", pause],
243
- ["seeking", hardAlign],
244
- ["seeked", hardAlign],
245
- ["ratechange", softAlign],
246
- ["timeupdate", softAlign]
247
- ];
248
- for (const [type, listener] of listeners) {
249
- transport.addEventListener(type, listener);
250
- }
251
- hardAlign();
252
- if (!transport.paused && !transport.ended) play();
253
- return () => {
254
- for (const [type, listener] of listeners) {
255
- transport.removeEventListener(type, listener);
256
- }
257
- followers.forEach((follower, index) => {
258
- follower.loop = ownLoops[index];
259
- });
260
- };
261
- }
262
-
263
- // src/modules/media/session.ts
264
- function newest(sources) {
265
- return sources.reduce((a, b) => b.order > a.order ? b : a);
266
- }
267
- function resolveMediaSession(sources) {
268
- if (sources.length === 0) return null;
269
- const ids = new Set(sources.map((source) => source.id));
270
- const wantsFollow = (source) => Boolean(source.follow) && source.follow !== source.id && ids.has(source.follow);
271
- const rootIds = new Set(
272
- sources.filter((source) => !wantsFollow(source)).map((source) => source.id)
273
- );
274
- const isFollower = (source) => wantsFollow(source) && rootIds.has(source.follow);
275
- const transport = newest(sources.filter((source) => !isFollower(source)));
276
- const followers = sources.filter((source) => isFollower(source) && source.follow === transport.id).sort((a, b) => a.order - b.order);
277
- const audioFollowers = followers.filter((source) => source.kind === "audio");
278
- return {
279
- audible: audioFollowers.length > 0 ? newest(audioFollowers) : transport,
280
- followers,
281
- transport
282
- };
283
- }
284
- function createMediaState(session) {
285
- if (!session) return DEFAULT_MEDIA_STATE;
286
- const { audible, transport } = session;
287
- return {
288
- audibleElement: audible.element,
289
- element: transport.element,
290
- hasMedia: true,
291
- isPlaying: transport.isPlaying,
292
- kind: transport.kind,
293
- loop: transport.loop,
294
- sourceId: transport.id
295
- };
296
- }
297
- function mediaStatesEqual(a, b) {
298
- return shallowEqual(a, b);
299
- }
300
- function mergeMediaSource(current, input, order) {
301
- return {
302
- controls: void 0,
303
- element: null,
304
- follow: null,
305
- isPlaying: false,
306
- kind: "audio",
307
- loop: false,
308
- ...current,
309
- ...input,
310
- order: current?.order ?? order
311
- };
312
- }
313
- function selectPageMedia(media) {
314
- if (!media) return null;
315
- if (typeof media === "string") return { src: media };
316
- return media.src ? media : null;
317
- }
318
- function findDisplacedAudio(entries, session, newId) {
319
- if (!session || session.transport.id !== newId) return [];
320
- const followerIds = new Set(session.followers.map((entry) => entry.id));
321
- return entries.filter(
322
- (entry) => entry.id !== newId && !followerIds.has(entry.id) && entry.kind === "audio" && entry.element !== null && !entry.element.paused
323
- );
324
- }
325
- var MediaContext = getOrCreateGlobalContext(
326
- "MediaContext",
327
- null
328
- );
329
- var NOOP_MEDIA_STORE = createStore(DEFAULT_MEDIA_STATE);
330
- function MediaProvider({ children }) {
331
- const [store] = useState(
332
- () => createStore(DEFAULT_MEDIA_STATE, { freezeSnapshots: false })
333
- );
334
- const sourcesRef = useRef(/* @__PURE__ */ new Map());
335
- const sessionRef = useRef(null);
336
- const orderRef = useRef(0);
337
- const bindingRef = useRef(null);
338
- const actions = useMemo(() => {
339
- const unbind = () => {
340
- bindingRef.current?.cleanup();
341
- bindingRef.current = null;
342
- };
343
- const rebind = (session) => {
344
- const transport = session?.transport.element ?? null;
345
- const followers = (session?.followers ?? []).map(
346
- (source) => source.element
347
- );
348
- const current = bindingRef.current;
349
- if (current && current.transport === transport && sameElements(current.followers, followers)) {
350
- return;
351
- }
352
- unbind();
353
- const live = followers.filter(
354
- (element) => element !== null
355
- );
356
- if (!transport || live.length === 0) return;
357
- bindingRef.current = {
358
- cleanup: bindFollowers(transport, live),
359
- followers,
360
- transport
361
- };
362
- };
363
- const commit = () => {
364
- const session = resolveMediaSession([...sourcesRef.current.values()]);
365
- sessionRef.current = session;
366
- rebind(session);
367
- const next = createMediaState(session);
368
- store.publish((prev) => mediaStatesEqual(prev, next) ? prev : next);
369
- };
370
- const patch = (id, changes) => {
371
- const current = sourcesRef.current.get(id);
372
- if (!current) return;
373
- sourcesRef.current.set(id, { ...current, ...changes });
374
- commit();
375
- };
376
- return {
377
- removeSource: (id) => {
378
- if (sourcesRef.current.delete(id)) commit();
379
- },
380
- setMuted: (muted) => {
381
- const audible = sessionRef.current?.audible;
382
- if (!audible) return;
383
- if (audible.controls?.setMuted) audible.controls.setMuted(muted);
384
- else if (audible.element) audible.element.muted = muted;
385
- },
386
- toggle: () => {
387
- const transport = sessionRef.current?.transport;
388
- if (!transport) return;
389
- if (transport.controls?.toggle) transport.controls.toggle();
390
- else toggleElement(transport.element);
391
- },
392
- toggleLoop: () => {
393
- const transport = sessionRef.current?.transport;
394
- if (!transport) return;
395
- if (transport.controls?.toggleLoop) {
396
- transport.controls.toggleLoop();
397
- return;
398
- }
399
- const loop = !transport.loop;
400
- if (transport.element) transport.element.loop = loop;
401
- patch(transport.id, { loop });
402
- },
403
- upsertSource: (input) => {
404
- const current = sourcesRef.current.get(input.id);
405
- if (!current) orderRef.current += 1;
406
- sourcesRef.current.set(
407
- input.id,
408
- mergeMediaSource(current, input, orderRef.current)
409
- );
410
- commit();
411
- if (!current) {
412
- findDisplacedAudio(
413
- [...sourcesRef.current.values()],
414
- sessionRef.current,
415
- input.id
416
- ).forEach((entry) => entry.element?.pause());
417
- }
418
- }
419
- };
420
- }, [store]);
421
- useEffect(
422
- () => () => {
423
- bindingRef.current?.cleanup();
424
- bindingRef.current = null;
425
- },
426
- []
427
- );
428
- const value = useMemo(
429
- () => ({ actions, store }),
430
- [actions, store]
431
- );
432
- return /* @__PURE__ */ jsx(MediaContext, { value, children });
433
- }
434
- function useMediaState() {
435
- const { store } = useRequiredContext(
436
- MediaContext,
437
- "useMediaState",
438
- "MediaProvider"
439
- );
440
- return useStore(store);
441
- }
442
- function useMediaActions() {
443
- return useRequiredContext(MediaContext, "useMediaActions", "MediaProvider").actions;
444
- }
445
- function useOptionalMediaState(selector, isEqual) {
446
- const ctx = useContext(MediaContext);
447
- return useStore(
448
- ctx?.store ?? NOOP_MEDIA_STORE,
449
- selector,
450
- isEqual
451
- );
452
- }
453
- function useOptionalMediaActions() {
454
- const ctx = useContext(MediaContext);
455
- return ctx?.actions ?? INERT_MEDIA_ACTIONS;
456
- }
457
- function useMedia(options) {
458
- const generatedId = useId();
459
- const id = options.id ?? `media-${generatedId}`;
460
- const { removeSource, upsertSource } = useMediaActions();
461
- const audioRef = useRef(null);
462
- const optionsRef = useRef(options);
463
- const { src, enabled = true } = options;
464
- const isEnabled = enabled && Boolean(src);
465
- useEffect(() => {
466
- optionsRef.current = options;
467
- });
468
- useEffect(() => {
469
- if (!isEnabled || !src) return void 0;
470
- const audio = new Audio();
471
- audio.preload = "auto";
472
- audio.src = src;
473
- audioRef.current = audio;
474
- const initial = optionsRef.current;
475
- audio.loop = Boolean(initial.loop);
476
- audio.muted = Boolean(initial.muted);
477
- if (typeof initial.volume === "number") {
478
- audio.volume = Math.min(1, Math.max(0, initial.volume));
479
- }
480
- upsertSource({
481
- element: audio,
482
- follow: initial.follow ?? null,
483
- id,
484
- isPlaying: false,
485
- kind: "audio",
486
- loop: audio.loop
487
- });
488
- const syncPlaying = () => upsertSource({ id, isPlaying: !audio.paused && !audio.ended });
489
- const events = ["play", "playing", "pause", "ended"];
490
- events.forEach((type) => audio.addEventListener(type, syncPlaying));
491
- if (!initial.follow && initial.autoplay !== false) {
492
- void Promise.resolve(audio.play()).catch(() => {
493
- });
494
- }
495
- return () => {
496
- events.forEach((type) => audio.removeEventListener(type, syncPlaying));
497
- audio.pause();
498
- audio.removeAttribute("src");
499
- audio.load();
500
- audioRef.current = null;
501
- removeSource(id);
502
- };
503
- }, [id, isEnabled, removeSource, src, upsertSource]);
504
- const { follow = null, loop, muted, volume } = options;
505
- useEffect(() => {
506
- const audio = audioRef.current;
507
- if (!audio) return;
508
- if (loop !== void 0 && !follow) audio.loop = loop;
509
- if (muted !== void 0) audio.muted = muted;
510
- if (volume !== void 0) audio.volume = Math.min(1, Math.max(0, volume));
511
- upsertSource({ follow, id, ...follow ? {} : { loop: audio.loop } });
512
- }, [follow, id, isEnabled, loop, muted, src, upsertSource, volume]);
513
- const play = useCallback(() => {
514
- const audio = audioRef.current;
515
- if (audio) void Promise.resolve(audio.play()).catch(() => {
516
- });
517
- }, []);
518
- const pause = useCallback(() => audioRef.current?.pause(), []);
519
- const toggle = useCallback(() => toggleElement(audioRef.current), []);
520
- return useMemo(
521
- () => ({ id, pause, play, toggle }),
522
- [id, pause, play, toggle]
523
- );
524
- }
525
-
526
- // src/modules/media/overlay.tsx
527
- function MediaSource(props) {
528
- useMedia(props);
529
- return null;
530
- }
531
- function MediaOverlay() {
532
- const page = useRegistryValue(
533
- "media",
534
- MEDIA_REGISTRY_KEY
535
- );
536
- useMedia({ ...page, id: PAGE_MEDIA_ID, src: page?.src });
537
- return null;
538
- }
539
-
540
- // src/modules/media/module.tsx
541
- function useMediaPage(_slice, page) {
542
- const actions = useMediaActions();
543
- return useMemo(
544
- () => ({
545
- ...actions,
546
- set: (media) => page.set({ media })
547
- }),
548
- [actions, page]
549
- );
550
- }
551
- var mediaModule = defineModule({
552
- id: "media",
553
- context: MediaContext,
554
- Provider: MediaProvider,
555
- Overlay: MediaOverlay,
556
- registry: {
557
- cleanupDelayMs: 600,
558
- keyPolicy: "singleton",
559
- lifecycle: "immediate",
560
- singletonKey: MEDIA_REGISTRY_KEY
561
- },
562
- page: {
563
- select: (config) => selectPageMedia(config.media),
564
- entries: (slice) => [
565
- { key: MEDIA_REGISTRY_KEY, value: slice }
566
- ],
567
- use: useMediaPage
568
- }
569
- });
570
-
571
- export { DEFAULT_MEDIA_STATE, INERT_MEDIA_ACTIONS, MEDIA_REGISTRY_KEY, MEDIA_SYNC_DRIFT_SECONDS, MediaContext, MediaOverlay, MediaProvider, MediaSource, NOOP_MEDIA_STORE, PAGE_MEDIA_ID, bindFollowers, createMediaState, findDisplacedAudio, mediaModule, mediaStatesEqual, mergeMediaSource, resolveMediaSession, safePlay, sameElements, selectPageMedia, toggleElement, useMedia, useMediaActions, useMediaState, useOptionalMediaActions, useOptionalMediaState };
2
+ export { DEFAULT_MEDIA_STATE, INERT_MEDIA_ACTIONS, MEDIA_REGISTRY_KEY, MEDIA_SYNC_DRIFT_SECONDS, MediaContext, MediaOverlay, MediaProvider, MediaSource, NOOP_MEDIA_STORE, PAGE_MEDIA_ID, bindFollowers, createMediaState, findDisplacedAudio, mediaModule, mediaStatesEqual, mergeMediaSource, resolveMediaSession, safePlay, sameElements, selectPageMedia, toggleElement, useMedia, useMediaActions, useMediaState, useOptionalMediaActions, useOptionalMediaState } from '../../chunk-R2YGFJDJ.js';
3
+ import '../../chunk-GF7TUX5I.js';
4
+ import '../../chunk-TV3WEF5G.js';
572
5
  //# sourceMappingURL=index.js.map
573
6
  //# sourceMappingURL=index.js.map