@omerdlw/base-framework 1.0.3 → 1.0.4
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.
- package/dist/index.js +5240 -5165
- package/dist/index.js.map +1 -1
- package/dist/kernel/compose.d.ts.map +1 -1
- package/dist/kernel/handlers.d.ts.map +1 -1
- package/dist/kernel/hooks.d.ts.map +1 -1
- package/dist/kernel/index.js.map +1 -1
- package/dist/kernel/operations.d.ts.map +1 -1
- package/dist/kernel/schema.d.ts +0 -2
- package/dist/kernel/schema.d.ts.map +1 -1
- package/dist/kernel/store.d.ts.map +1 -1
- package/dist/kernel/types.d.ts.map +1 -1
- package/dist/kernel/utils.d.ts +0 -2
- package/dist/kernel/utils.d.ts.map +1 -1
- package/dist/modules/ambient/color.d.ts +16 -0
- package/dist/modules/ambient/color.d.ts.map +1 -0
- package/dist/modules/ambient/constants.d.ts +0 -17
- package/dist/modules/ambient/constants.d.ts.map +1 -1
- package/dist/modules/ambient/context.d.ts +1 -7
- package/dist/modules/ambient/context.d.ts.map +1 -1
- package/dist/modules/ambient/dom.d.ts +19 -0
- package/dist/modules/ambient/dom.d.ts.map +1 -0
- package/dist/modules/ambient/extractor.d.ts +5 -0
- package/dist/modules/ambient/extractor.d.ts.map +1 -0
- package/dist/modules/ambient/hooks.d.ts +9 -0
- package/dist/modules/ambient/hooks.d.ts.map +1 -0
- package/dist/modules/ambient/index.d.ts +7 -4
- package/dist/modules/ambient/index.d.ts.map +1 -1
- package/dist/modules/ambient/index.js +66 -60
- package/dist/modules/ambient/index.js.map +1 -1
- package/dist/modules/ambient/module.d.ts +5 -1
- package/dist/modules/ambient/module.d.ts.map +1 -1
- package/dist/modules/background/constants.d.ts +1 -10
- package/dist/modules/background/constants.d.ts.map +1 -1
- package/dist/modules/background/context.d.ts +1 -13
- package/dist/modules/background/context.d.ts.map +1 -1
- package/dist/modules/background/hooks.d.ts +13 -118
- package/dist/modules/background/hooks.d.ts.map +1 -1
- package/dist/modules/background/index.d.ts +8 -3
- package/dist/modules/background/index.d.ts.map +1 -1
- package/dist/modules/background/index.js +975 -991
- package/dist/modules/background/index.js.map +1 -1
- package/dist/modules/background/module.d.ts +1 -0
- package/dist/modules/background/module.d.ts.map +1 -1
- package/dist/modules/background/overlay.d.ts +93 -2
- package/dist/modules/background/overlay.d.ts.map +1 -1
- package/dist/modules/background/playback.d.ts +10 -0
- package/dist/modules/background/playback.d.ts.map +1 -0
- package/dist/modules/background/state.d.ts +9 -0
- package/dist/modules/background/state.d.ts.map +1 -0
- package/dist/modules/background/{utils.d.ts → visual.d.ts} +6 -14
- package/dist/modules/background/visual.d.ts.map +1 -0
- package/dist/modules/background/youtube/player.d.ts +28 -0
- package/dist/modules/background/youtube/player.d.ts.map +1 -0
- package/dist/modules/context-menu/context.d.ts +1 -10
- package/dist/modules/context-menu/context.d.ts.map +1 -1
- package/dist/modules/context-menu/dom.d.ts +8 -0
- package/dist/modules/context-menu/dom.d.ts.map +1 -0
- package/dist/modules/context-menu/hooks.d.ts +11 -11
- package/dist/modules/context-menu/hooks.d.ts.map +1 -1
- package/dist/modules/context-menu/index.d.ts +8 -3
- package/dist/modules/context-menu/index.d.ts.map +1 -1
- package/dist/modules/context-menu/index.js +97 -101
- package/dist/modules/context-menu/index.js.map +1 -1
- package/dist/modules/context-menu/{utils.d.ts → items.d.ts} +2 -9
- package/dist/modules/context-menu/items.d.ts.map +1 -0
- package/dist/modules/context-menu/module.d.ts.map +1 -1
- package/dist/modules/context-menu/overlay.d.ts +13 -1
- package/dist/modules/context-menu/overlay.d.ts.map +1 -1
- package/dist/modules/context-menu/state.d.ts +1 -0
- package/dist/modules/context-menu/state.d.ts.map +1 -1
- package/dist/modules/controls/{utils.d.ts → entries.d.ts} +6 -5
- package/dist/modules/controls/entries.d.ts.map +1 -0
- package/dist/modules/controls/hooks.d.ts +0 -7
- package/dist/modules/controls/hooks.d.ts.map +1 -1
- package/dist/modules/controls/index.d.ts +5 -3
- package/dist/modules/controls/index.d.ts.map +1 -1
- package/dist/modules/controls/index.js +66 -61
- package/dist/modules/controls/index.js.map +1 -1
- package/dist/modules/controls/layout.d.ts +7 -0
- package/dist/modules/controls/layout.d.ts.map +1 -0
- package/dist/modules/controls/overlay.d.ts +9 -0
- package/dist/modules/controls/overlay.d.ts.map +1 -1
- package/dist/modules/dock/cards.d.ts.map +1 -1
- package/dist/modules/dock/dom.d.ts +24 -0
- package/dist/modules/dock/dom.d.ts.map +1 -0
- package/dist/modules/dock/helpers.d.ts +25 -0
- package/dist/modules/dock/helpers.d.ts.map +1 -0
- package/dist/modules/dock/hooks.d.ts +3 -918
- package/dist/modules/dock/hooks.d.ts.map +1 -1
- package/dist/modules/dock/index.d.ts +3 -2
- package/dist/modules/dock/index.d.ts.map +1 -1
- package/dist/modules/dock/index.js +3091 -3079
- package/dist/modules/dock/index.js.map +1 -1
- package/dist/modules/dock/layout.d.ts +26 -0
- package/dist/modules/dock/layout.d.ts.map +1 -0
- package/dist/modules/dock/module.d.ts.map +1 -1
- package/dist/modules/dock/overlay.d.ts.map +1 -1
- package/dist/modules/dock/paths.d.ts +10 -0
- package/dist/modules/dock/paths.d.ts.map +1 -0
- package/dist/modules/dock/provider.d.ts.map +1 -1
- package/dist/modules/dock/runtime/display.d.ts.map +1 -1
- package/dist/modules/dock/runtime/dock.d.ts.map +1 -1
- package/dist/modules/dock/runtime/pipeline.d.ts +32 -0
- package/dist/modules/dock/runtime/pipeline.d.ts.map +1 -0
- package/dist/modules/dock/status/events.d.ts.map +1 -1
- package/dist/modules/dock/styles.d.ts +900 -0
- package/dist/modules/dock/styles.d.ts.map +1 -0
- package/dist/modules/dock/surface/context.d.ts +1 -2
- package/dist/modules/dock/surface/context.d.ts.map +1 -1
- package/dist/modules/dock/surface/definition.d.ts.map +1 -1
- package/dist/modules/dock/surface/helpers.d.ts +7 -0
- package/dist/modules/dock/surface/helpers.d.ts.map +1 -0
- package/dist/modules/dock/surface/hooks.d.ts.map +1 -1
- package/dist/modules/dock/surface/machine.d.ts.map +1 -1
- package/dist/modules/dock/surface/stack.d.ts.map +1 -1
- package/dist/modules/dock/surface/view-model.d.ts.map +1 -1
- package/dist/modules/dock/types.d.ts.map +1 -1
- package/dist/modules/index.js +4861 -4788
- package/dist/modules/index.js.map +1 -1
- package/dist/modules/loading/context.d.ts +2 -13
- package/dist/modules/loading/context.d.ts.map +1 -1
- package/dist/modules/loading/hooks.d.ts +15 -2
- package/dist/modules/loading/hooks.d.ts.map +1 -1
- package/dist/modules/loading/index.d.ts +3 -2
- package/dist/modules/loading/index.d.ts.map +1 -1
- package/dist/modules/loading/index.js +38 -34
- package/dist/modules/loading/index.js.map +1 -1
- package/dist/modules/loading/module.d.ts.map +1 -1
- package/dist/modules/loading/state.d.ts +6 -0
- package/dist/modules/loading/state.d.ts.map +1 -0
- package/dist/modules/media/constants.d.ts +0 -1
- package/dist/modules/media/constants.d.ts.map +1 -1
- package/dist/modules/media/context.d.ts +2 -6
- package/dist/modules/media/context.d.ts.map +1 -1
- package/dist/modules/media/hooks.d.ts +6 -1
- package/dist/modules/media/hooks.d.ts.map +1 -1
- package/dist/modules/media/index.d.ts +4 -3
- package/dist/modules/media/index.d.ts.map +1 -1
- package/dist/modules/media/index.js +100 -98
- package/dist/modules/media/index.js.map +1 -1
- package/dist/modules/media/module.d.ts.map +1 -1
- package/dist/modules/media/overlay.d.ts +0 -5
- package/dist/modules/media/overlay.d.ts.map +1 -1
- package/dist/modules/media/playback.d.ts +5 -0
- package/dist/modules/media/playback.d.ts.map +1 -0
- package/dist/modules/media/session.d.ts +8 -0
- package/dist/modules/media/session.d.ts.map +1 -0
- package/dist/modules/media/types.d.ts +0 -1
- package/dist/modules/media/types.d.ts.map +1 -1
- package/dist/modules/modal/context.d.ts +1 -12
- package/dist/modules/modal/context.d.ts.map +1 -1
- package/dist/modules/modal/dom.d.ts +4 -0
- package/dist/modules/modal/dom.d.ts.map +1 -0
- package/dist/modules/modal/header.d.ts +7 -0
- package/dist/modules/modal/header.d.ts.map +1 -0
- package/dist/modules/modal/hooks.d.ts +12 -1
- package/dist/modules/modal/hooks.d.ts.map +1 -1
- package/dist/modules/modal/identity.d.ts +7 -0
- package/dist/modules/modal/identity.d.ts.map +1 -0
- package/dist/modules/modal/index.d.ts +9 -4
- package/dist/modules/modal/index.d.ts.map +1 -1
- package/dist/modules/modal/index.js +118 -86
- package/dist/modules/modal/index.js.map +1 -1
- package/dist/modules/modal/layout.d.ts +13 -0
- package/dist/modules/modal/layout.d.ts.map +1 -0
- package/dist/modules/modal/module.d.ts.map +1 -1
- package/dist/modules/modal/overlay.d.ts.map +1 -1
- package/dist/modules/modal/types.d.ts.map +1 -1
- package/dist/modules/notification/context.d.ts +2 -8
- package/dist/modules/notification/context.d.ts.map +1 -1
- package/dist/modules/notification/hooks.d.ts +8 -1
- package/dist/modules/notification/hooks.d.ts.map +1 -1
- package/dist/modules/notification/index.d.ts +4 -3
- package/dist/modules/notification/index.d.ts.map +1 -1
- package/dist/modules/notification/index.js +56 -46
- package/dist/modules/notification/index.js.map +1 -1
- package/dist/modules/notification/state.d.ts +17 -0
- package/dist/modules/notification/state.d.ts.map +1 -0
- package/dist/provider.js.map +1 -1
- package/docs/modules/ambient.md +12 -8
- package/docs/modules/background.md +15 -13
- package/docs/modules/context-menu.md +13 -13
- package/docs/modules/controls.md +4 -3
- package/docs/modules/dock.md +8 -2
- package/docs/modules/loading.md +11 -11
- package/docs/modules/media.md +8 -7
- package/docs/modules/modal.md +4 -1
- package/docs/modules/notification.md +4 -4
- package/package.json +1 -1
- package/dist/modules/ambient/utils.d.ts +0 -18
- package/dist/modules/ambient/utils.d.ts.map +0 -1
- package/dist/modules/background/utils.d.ts.map +0 -1
- package/dist/modules/context-menu/utils.d.ts.map +0 -1
- package/dist/modules/controls/utils.d.ts.map +0 -1
- package/dist/modules/dock/utils.d.ts +0 -93
- package/dist/modules/dock/utils.d.ts.map +0 -1
- package/dist/modules/loading/utils.d.ts +0 -4
- package/dist/modules/loading/utils.d.ts.map +0 -1
- package/dist/modules/media/utils.d.ts +0 -17
- package/dist/modules/media/utils.d.ts.map +0 -1
- package/dist/modules/modal/utils.d.ts +0 -31
- package/dist/modules/modal/utils.d.ts.map +0 -1
- package/dist/modules/notification/utils.d.ts +0 -9
- package/dist/modules/notification/utils.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../src/modules/media/hooks.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../src/modules/media/hooks.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,UAAU,EAChB,MAAM,SAAS,CAAC;AAEjB,wBAAgB,aAAa,IAAI,UAAU,CAO1C;AAED,wBAAgB,eAAe,IAAI,YAAY,CAG9C;AAED,wBAAgB,qBAAqB,IAAI,UAAU,CAAC;AACpD,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,CAAC,EAClC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,GAChC,CAAC,CAAC;AAaL,wBAAgB,uBAAuB,IAAI,YAAY,CAGtD;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,WAAW,CA4E3D"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export { MediaContext, MediaProvider,
|
|
2
|
-
export { useMedia } from "./hooks";
|
|
1
|
+
export { MediaContext, MediaProvider, NOOP_MEDIA_STORE, } from "./context";
|
|
2
|
+
export { useMedia, useMediaActions, useMediaState, useOptionalMediaActions, useOptionalMediaState, } from "./hooks";
|
|
3
3
|
export { mediaModule } from "./module";
|
|
4
4
|
export { MediaOverlay, MediaSource } from "./overlay";
|
|
5
5
|
export { DEFAULT_MEDIA_STATE, INERT_MEDIA_ACTIONS, MEDIA_REGISTRY_KEY, MEDIA_SYNC_DRIFT_SECONDS, PAGE_MEDIA_ID, } from "./constants";
|
|
6
|
-
export {
|
|
6
|
+
export { createMediaState, findDisplacedAudio, mediaStatesEqual, mergeMediaSource, resolveMediaSession, selectPageMedia, } from "./session";
|
|
7
|
+
export { bindFollowers, safePlay, sameElements, toggleElement, } from "./playback";
|
|
7
8
|
export type * from "./types";
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/modules/media/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,eAAe,EACf,aAAa,EACb,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/modules/media/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,gBAAgB,GACjB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,QAAQ,EACR,eAAe,EACf,aAAa,EACb,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,mBAAmB,SAAS,CAAC"}
|
|
@@ -2,45 +2,13 @@
|
|
|
2
2
|
import { createContext, useState, useRef, useMemo, useEffect, useContext, useId, useCallback, use, useSyncExternalStore } from 'react';
|
|
3
3
|
import { jsx } from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
|
-
function
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
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);
|
|
9
10
|
}
|
|
10
|
-
return
|
|
11
|
-
}
|
|
12
|
-
function useStore(store, selector = (state) => state, isEqual = Object.is) {
|
|
13
|
-
const cacheRef = useRef({
|
|
14
|
-
isEqual: null,
|
|
15
|
-
selected: void 0,
|
|
16
|
-
selector: null,
|
|
17
|
-
snapshot: null
|
|
18
|
-
});
|
|
19
|
-
const getSelectedSnapshot = useCallback(() => {
|
|
20
|
-
const snapshot = store.getSnapshot();
|
|
21
|
-
const cache = cacheRef.current;
|
|
22
|
-
if (cache.snapshot === snapshot && cache.selector === selector && cache.isEqual === isEqual) {
|
|
23
|
-
return cache.selected;
|
|
24
|
-
}
|
|
25
|
-
const selected = selector(snapshot);
|
|
26
|
-
if (cache.snapshot !== null && cache.isEqual === isEqual && isEqual(cache.selected, selected)) {
|
|
27
|
-
cache.snapshot = snapshot;
|
|
28
|
-
cache.selector = selector;
|
|
29
|
-
return cache.selected;
|
|
30
|
-
}
|
|
31
|
-
cacheRef.current = {
|
|
32
|
-
isEqual,
|
|
33
|
-
selected,
|
|
34
|
-
selector,
|
|
35
|
-
snapshot
|
|
36
|
-
};
|
|
37
|
-
return selected;
|
|
38
|
-
}, [isEqual, selector, store]);
|
|
39
|
-
return useSyncExternalStore(
|
|
40
|
-
store.subscribe,
|
|
41
|
-
getSelectedSnapshot,
|
|
42
|
-
getSelectedSnapshot
|
|
43
|
-
);
|
|
11
|
+
return store[sym];
|
|
44
12
|
}
|
|
45
13
|
|
|
46
14
|
// src/utils/object.ts
|
|
@@ -132,13 +100,45 @@ function createStore(initialState, { freezeSnapshots = true } = {}) {
|
|
|
132
100
|
}
|
|
133
101
|
});
|
|
134
102
|
}
|
|
135
|
-
function
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
store[sym] = createContext(defaultValue);
|
|
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}`);
|
|
140
107
|
}
|
|
141
|
-
return
|
|
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
142
|
}
|
|
143
143
|
var RegistryContext = getOrCreateGlobalContext(
|
|
144
144
|
"RegistryContext",
|
|
@@ -194,58 +194,9 @@ var MEDIA_SYNC_DRIFT_SECONDS = 0.3;
|
|
|
194
194
|
var MEDIA_REGISTRY_KEY = "page-media";
|
|
195
195
|
var PAGE_MEDIA_ID = "page";
|
|
196
196
|
|
|
197
|
-
// src/modules/media/
|
|
197
|
+
// src/modules/media/playback.ts
|
|
198
198
|
var noop = () => {
|
|
199
199
|
};
|
|
200
|
-
function newest(sources) {
|
|
201
|
-
return sources.reduce((a, b) => b.order > a.order ? b : a);
|
|
202
|
-
}
|
|
203
|
-
function resolveMediaSession(sources) {
|
|
204
|
-
if (sources.length === 0) return null;
|
|
205
|
-
const ids = new Set(sources.map((source) => source.id));
|
|
206
|
-
const wantsFollow = (source) => Boolean(source.follow) && source.follow !== source.id && ids.has(source.follow);
|
|
207
|
-
const rootIds = new Set(
|
|
208
|
-
sources.filter((source) => !wantsFollow(source)).map((source) => source.id)
|
|
209
|
-
);
|
|
210
|
-
const isFollower = (source) => wantsFollow(source) && rootIds.has(source.follow);
|
|
211
|
-
const transport = newest(sources.filter((source) => !isFollower(source)));
|
|
212
|
-
const followers = sources.filter((source) => isFollower(source) && source.follow === transport.id).sort((a, b) => a.order - b.order);
|
|
213
|
-
const audioFollowers = followers.filter((source) => source.kind === "audio");
|
|
214
|
-
return {
|
|
215
|
-
audible: audioFollowers.length > 0 ? newest(audioFollowers) : transport,
|
|
216
|
-
followers,
|
|
217
|
-
transport
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
function createMediaState(session) {
|
|
221
|
-
if (!session) return DEFAULT_MEDIA_STATE;
|
|
222
|
-
const { audible, transport } = session;
|
|
223
|
-
return {
|
|
224
|
-
audibleElement: audible.element,
|
|
225
|
-
element: transport.element,
|
|
226
|
-
hasMedia: true,
|
|
227
|
-
isPlaying: transport.isPlaying,
|
|
228
|
-
kind: transport.kind,
|
|
229
|
-
loop: transport.loop,
|
|
230
|
-
sourceId: transport.id
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
function mediaStatesEqual(a, b) {
|
|
234
|
-
return shallowEqual(a, b);
|
|
235
|
-
}
|
|
236
|
-
function mergeMediaSource(current, input, order) {
|
|
237
|
-
return {
|
|
238
|
-
controls: void 0,
|
|
239
|
-
element: null,
|
|
240
|
-
follow: null,
|
|
241
|
-
isPlaying: false,
|
|
242
|
-
kind: "audio",
|
|
243
|
-
loop: false,
|
|
244
|
-
...current,
|
|
245
|
-
...input,
|
|
246
|
-
order: current?.order ?? order
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
200
|
function toggleElement(element) {
|
|
250
201
|
if (!element) return;
|
|
251
202
|
if (element.paused || element.ended) {
|
|
@@ -260,6 +211,9 @@ function safePlay(element) {
|
|
|
260
211
|
} catch {
|
|
261
212
|
}
|
|
262
213
|
}
|
|
214
|
+
function sameElements(a, b) {
|
|
215
|
+
return a.length === b.length && a.every((element, index) => element === b[index]);
|
|
216
|
+
}
|
|
263
217
|
function bindFollowers(transport, followers) {
|
|
264
218
|
const ownLoops = followers.map((follower) => follower.loop);
|
|
265
219
|
const align = (hard) => {
|
|
@@ -305,8 +259,56 @@ function bindFollowers(transport, followers) {
|
|
|
305
259
|
});
|
|
306
260
|
};
|
|
307
261
|
}
|
|
308
|
-
|
|
309
|
-
|
|
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
|
+
};
|
|
310
312
|
}
|
|
311
313
|
function selectPageMedia(media) {
|
|
312
314
|
if (!media) return null;
|
|
@@ -324,6 +326,7 @@ var MediaContext = getOrCreateGlobalContext(
|
|
|
324
326
|
"MediaContext",
|
|
325
327
|
null
|
|
326
328
|
);
|
|
329
|
+
var NOOP_MEDIA_STORE = createStore(DEFAULT_MEDIA_STATE);
|
|
327
330
|
function MediaProvider({ children }) {
|
|
328
331
|
const [store] = useState(
|
|
329
332
|
() => createStore(DEFAULT_MEDIA_STATE, { freezeSnapshots: false })
|
|
@@ -439,7 +442,6 @@ function useMediaState() {
|
|
|
439
442
|
function useMediaActions() {
|
|
440
443
|
return useRequiredContext(MediaContext, "useMediaActions", "MediaProvider").actions;
|
|
441
444
|
}
|
|
442
|
-
var NOOP_MEDIA_STORE = createStore(DEFAULT_MEDIA_STATE);
|
|
443
445
|
function useOptionalMediaState(selector, isEqual) {
|
|
444
446
|
const ctx = useContext(MediaContext);
|
|
445
447
|
return useStore(
|
|
@@ -566,6 +568,6 @@ var mediaModule = defineModule({
|
|
|
566
568
|
}
|
|
567
569
|
});
|
|
568
570
|
|
|
569
|
-
export { DEFAULT_MEDIA_STATE, INERT_MEDIA_ACTIONS, MEDIA_REGISTRY_KEY, MEDIA_SYNC_DRIFT_SECONDS, MediaContext, MediaOverlay, MediaProvider, MediaSource, PAGE_MEDIA_ID, bindFollowers, createMediaState, mediaModule, resolveMediaSession, selectPageMedia, useMedia, useMediaActions, useMediaState, useOptionalMediaActions, useOptionalMediaState };
|
|
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 };
|
|
570
572
|
//# sourceMappingURL=index.js.map
|
|
571
573
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/hooks/use-required-context.ts","../../../src/hooks/use-store.ts","../../../src/utils/object.ts","../../../src/utils/report.ts","../../../src/utils/store.ts","../../../src/kernel/context-registry.ts","../../../src/kernel/provider.tsx","../../../src/kernel/module.tsx","../../../src/modules/media/constants.ts","../../../src/modules/media/utils.ts","../../../src/modules/media/context.tsx","../../../src/modules/media/hooks.ts","../../../src/modules/media/overlay.tsx","../../../src/modules/media/module.tsx"],"names":["useCallback","useSyncExternalStore","useState","useRef","useMemo","jsx","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["\"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","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","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","\"use client\";\n\nimport {\n useCallback,\n useMemo,\n useState,\n useSyncExternalStore,\n type ReactNode,\n} from \"react\";\nimport { useRequiredContext } from \"@/hooks\";\nimport { getOrCreateGlobalContext } from \"./context-registry\";\n\nimport type {\n RegistryDefinitions,\n RegistrySchema,\n RegistryStore,\n} from \"./types\";\nimport { createRegistryStore, type InitialRegistryEntries } from \"./store\";\n\ntype RegistryValueOf<K extends string> = K extends keyof RegistrySchema\n ? RegistrySchema[K]\n : unknown;\n\ninterface RegistryContextValue {\n actions: Pick<\n RegistryStore,\n \"batch\" | \"register\" | \"transaction\" | \"unregister\"\n >;\n subscription: Pick<\n RegistryStore,\n \"getEntriesSnapshot\" | \"getSnapshot\" | \"subscribe\"\n >;\n}\n\nconst RegistryContext = getOrCreateGlobalContext<RegistryContextValue | null>(\n\n \"RegistryContext\",\n null,\n);\n\nexport function RegistryProvider({\n children,\n definitions,\n initialEntries = [],\n}: {\n children?: ReactNode;\n definitions?: RegistryDefinitions;\n initialEntries?: InitialRegistryEntries;\n}) {\n const [store] = useState(() =>\n createRegistryStore(initialEntries, definitions),\n );\n\n const contextValue = useMemo(\n () => ({\n actions: {\n batch: store.batch,\n register: store.register,\n transaction: store.transaction,\n unregister: store.unregister,\n },\n subscription: {\n getEntriesSnapshot: store.getEntriesSnapshot,\n getSnapshot: store.getSnapshot,\n subscribe: store.subscribe,\n },\n }),\n [store],\n );\n\n return <RegistryContext value={contextValue}>{children}</RegistryContext>;\n}\n\nexport function useRegistryActions(): RegistryContextValue[\"actions\"] {\n return useRequiredContext(\n RegistryContext,\n \"useRegistryActions\",\n \"RegistryProvider\",\n ).actions;\n}\n\nfunction useRegistrySubscription(): RegistryContextValue[\"subscription\"] {\n return useRequiredContext(\n RegistryContext,\n \"useRegistrySubscription\",\n \"RegistryProvider\",\n ).subscription;\n}\n\nexport function useRegistryValue<\n K extends string = string,\n T = RegistryValueOf<K>,\n>(type: K, key: string): T | undefined {\n const { getSnapshot, subscribe } = useRegistrySubscription();\n\n const subscribeToKey = useCallback(\n (listener: () => void) => subscribe(type, key, listener),\n [key, subscribe, type],\n );\n const getValue = useCallback(\n () => getSnapshot<K, T>(type, key),\n [getSnapshot, key, type],\n );\n\n return useSyncExternalStore(subscribeToKey, getValue, getValue);\n}\n\nexport function useRegistryEntries<\n K extends string = string,\n T = RegistryValueOf<K>,\n>(type: K): Record<string, T> {\n const { getEntriesSnapshot, subscribe } = useRegistrySubscription();\n\n const subscribeToType = useCallback(\n (listener: () => void) => subscribe(type, null, listener),\n [subscribe, type],\n );\n const getEntries = useCallback(\n () => getEntriesSnapshot<K, T>(type),\n [getEntriesSnapshot, type],\n );\n\n return useSyncExternalStore(subscribeToType, getEntries, getEntries);\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","import { type MediaActions, type MediaState } from \"./types\";\n\nexport const DEFAULT_MEDIA_STATE: MediaState = Object.freeze({\n audibleElement: null,\n element: null,\n hasMedia: false,\n isPlaying: false,\n kind: null,\n loop: false,\n sourceId: null,\n});\n\nexport const INERT_MEDIA_ACTIONS: MediaActions = Object.freeze({\n removeSource: () => {},\n setMuted: () => {},\n toggle: () => {},\n toggleLoop: () => {},\n upsertSource: () => {},\n});\n\n\nexport const MEDIA_SYNC_DRIFT_SECONDS = 0.3;\n\nexport const MEDIA_REGISTRY_KEY = \"page-media\";\n\n/** Id of the audio source registered through `usePage({ media })`. */\nexport const PAGE_MEDIA_ID = \"page\";\n","import { shallowEqual } from \"@/utils\";\nimport { DEFAULT_MEDIA_STATE, MEDIA_SYNC_DRIFT_SECONDS } from \"./constants\";\nimport {\n type MediaSession,\n type MediaEntry,\n type MediaEntryInput,\n type MediaPageConfig,\n type MediaPageOptions,\n type MediaState,\n} from \"./types\";\n\nconst noop = () => {};\n\nfunction newest(sources: readonly MediaEntry[]): MediaEntry {\n return sources.reduce((a, b) => (b.order > a.order ? b : a));\n}\n\nexport function resolveMediaSession(\n sources: readonly MediaEntry[],\n): MediaSession | null {\n if (sources.length === 0) return null;\n\n const ids = new Set(sources.map((source) => source.id));\n const wantsFollow = (source: MediaEntry) =>\n Boolean(source.follow) &&\n source.follow !== source.id &&\n ids.has(source.follow!);\n const rootIds = new Set(\n sources.filter((source) => !wantsFollow(source)).map((source) => source.id),\n );\n const isFollower = (source: MediaEntry) =>\n wantsFollow(source) && rootIds.has(source.follow!);\n\n const transport = newest(sources.filter((source) => !isFollower(source)));\n const followers = sources\n .filter((source) => isFollower(source) && source.follow === transport.id)\n .sort((a, b) => a.order - b.order);\n const audioFollowers = followers.filter((source) => source.kind === \"audio\");\n\n return {\n audible: audioFollowers.length > 0 ? newest(audioFollowers) : transport,\n followers,\n transport,\n };\n}\n\nexport function createMediaState(session: MediaSession | null): MediaState {\n if (!session) return DEFAULT_MEDIA_STATE;\n const { audible, transport } = session;\n return {\n audibleElement: audible.element,\n element: transport.element,\n hasMedia: true,\n isPlaying: transport.isPlaying,\n kind: transport.kind,\n loop: transport.loop,\n sourceId: transport.id,\n };\n}\n\nexport function mediaStatesEqual(a: MediaState, b: MediaState): boolean {\n return shallowEqual(a, b);\n}\n\nexport function mergeMediaSource(\n current: MediaEntry | undefined,\n input: MediaEntryInput,\n order: number,\n): MediaEntry {\n return {\n controls: undefined,\n element: null,\n follow: null,\n isPlaying: false,\n kind: \"audio\",\n loop: false,\n ...current,\n ...input,\n order: current?.order ?? order,\n };\n}\n\nexport function toggleElement(element: HTMLMediaElement | null): void {\n if (!element) return;\n if (element.paused || element.ended) {\n void Promise.resolve(element.play()).catch(noop);\n } else {\n element.pause();\n }\n}\n\nexport function safePlay(element: HTMLMediaElement): void {\n try {\n void Promise.resolve(element.play()).catch(noop);\n } catch {\n /* autoplay blocked or element detached */\n }\n}\n\nexport function bindFollowers(\n transport: HTMLMediaElement,\n followers: readonly HTMLMediaElement[],\n): () => void {\n const ownLoops = followers.map((follower) => follower.loop);\n\n const align = (hard: boolean) => {\n const time = Number(transport.currentTime) || 0;\n for (const follower of followers) {\n follower.loop = false;\n if (follower.playbackRate !== transport.playbackRate) {\n follower.playbackRate = transport.playbackRate;\n }\n const drift = Math.abs((Number(follower.currentTime) || 0) - time);\n if (hard || drift > MEDIA_SYNC_DRIFT_SECONDS) follower.currentTime = time;\n }\n };\n const play = () => {\n align(false);\n followers.forEach(safePlay);\n };\n const pause = () => followers.forEach((follower) => follower.pause());\n const hardAlign = () => align(true);\n const softAlign = () => align(false);\n\n const listeners: [string, () => void][] = [\n [\"play\", play],\n [\"playing\", play],\n [\"pause\", pause],\n [\"waiting\", pause],\n [\"ended\", pause],\n [\"seeking\", hardAlign],\n [\"seeked\", hardAlign],\n [\"ratechange\", softAlign],\n [\"timeupdate\", softAlign],\n ];\n for (const [type, listener] of listeners) {\n transport.addEventListener(type, listener);\n }\n\n hardAlign();\n if (!transport.paused && !transport.ended) play();\n\n return () => {\n for (const [type, listener] of listeners) {\n transport.removeEventListener(type, listener);\n }\n followers.forEach((follower, index) => {\n follower.loop = ownLoops[index];\n });\n };\n}\n\nexport function sameElements(\n a: readonly (HTMLMediaElement | null)[],\n b: readonly (HTMLMediaElement | null)[],\n): boolean {\n return (\n a.length === b.length && a.every((element, index) => element === b[index])\n );\n}\n\nexport function selectPageMedia(\n media: MediaPageConfig | null | undefined,\n): MediaPageOptions | null {\n if (!media) return null;\n if (typeof media === \"string\") return { src: media };\n return media.src ? media : null;\n}\n\n/**\n * Standalone audio that a newly registered source pushes out of the controls.\n * Two independent tracks would otherwise play over each other while the dock\n * only controls the newest.\n */\nexport function findDisplacedAudio(\n entries: readonly MediaEntry[],\n session: MediaSession | null,\n newId: string,\n): MediaEntry[] {\n if (!session || session.transport.id !== newId) return [];\n const followerIds = new Set(session.followers.map((entry) => entry.id));\n return entries.filter(\n (entry) =>\n entry.id !== newId &&\n !followerIds.has(entry.id) &&\n entry.kind === \"audio\" &&\n entry.element !== null &&\n !entry.element.paused,\n );\n}\n","\"use client\";\n\nimport { useContext, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useRequiredContext, useStore } from \"@/hooks\";\nimport { getOrCreateGlobalContext } from \"@/kernel\";\nimport { createStore } from \"@/utils\";\n\nimport { DEFAULT_MEDIA_STATE, INERT_MEDIA_ACTIONS } from \"./constants\";\n\nimport {\n type MediaActions,\n type MediaContextValue,\n type MediaProviderProps,\n type MediaSession,\n type MediaEntry,\n type MediaState,\n} from \"./types\";\nimport {\n bindFollowers,\n createMediaState,\n findDisplacedAudio,\n mediaStatesEqual,\n mergeMediaSource,\n resolveMediaSession,\n sameElements,\n toggleElement,\n} from \"./utils\";\n\nexport const MediaContext = getOrCreateGlobalContext<MediaContextValue | null>(\n\n \"MediaContext\",\n null,\n);\n\ninterface Binding {\n cleanup: () => void;\n followers: readonly (HTMLMediaElement | null)[];\n transport: HTMLMediaElement;\n}\n\nexport function MediaProvider({ children }: MediaProviderProps) {\n const [store] = useState(() =>\n createStore<MediaState>(DEFAULT_MEDIA_STATE, { freezeSnapshots: false }),\n );\n const sourcesRef = useRef(new Map<string, MediaEntry>());\n const sessionRef = useRef<MediaSession | null>(null);\n const orderRef = useRef(0);\n const bindingRef = useRef<Binding | null>(null);\n\n const actions = useMemo<MediaActions>(() => {\n const unbind = () => {\n bindingRef.current?.cleanup();\n bindingRef.current = null;\n };\n\n const rebind = (session: MediaSession | null) => {\n const transport = session?.transport.element ?? null;\n const followers = (session?.followers ?? []).map(\n (source) => source.element,\n );\n const current = bindingRef.current;\n if (\n current &&\n current.transport === transport &&\n sameElements(current.followers, followers)\n ) {\n return;\n }\n unbind();\n const live = followers.filter(\n (element): element is HTMLMediaElement => element !== null,\n );\n if (!transport || live.length === 0) return;\n bindingRef.current = {\n cleanup: bindFollowers(transport, live),\n followers,\n transport,\n };\n };\n\n const commit = () => {\n const session = resolveMediaSession([...sourcesRef.current.values()]);\n sessionRef.current = session;\n rebind(session);\n const next = createMediaState(session);\n store.publish((prev) => (mediaStatesEqual(prev, next) ? prev : next));\n };\n\n const patch = (id: string, changes: Partial<MediaEntry>) => {\n const current = sourcesRef.current.get(id);\n if (!current) return;\n sourcesRef.current.set(id, { ...current, ...changes });\n commit();\n };\n\n return {\n removeSource: (id) => {\n if (sourcesRef.current.delete(id)) commit();\n },\n setMuted: (muted) => {\n const audible = sessionRef.current?.audible;\n if (!audible) return;\n if (audible.controls?.setMuted) audible.controls.setMuted(muted);\n else if (audible.element) audible.element.muted = muted;\n },\n toggle: () => {\n const transport = sessionRef.current?.transport;\n if (!transport) return;\n if (transport.controls?.toggle) transport.controls.toggle();\n else toggleElement(transport.element);\n },\n toggleLoop: () => {\n const transport = sessionRef.current?.transport;\n if (!transport) return;\n if (transport.controls?.toggleLoop) {\n transport.controls.toggleLoop();\n return;\n }\n const loop = !transport.loop;\n if (transport.element) transport.element.loop = loop;\n patch(transport.id, { loop });\n },\n upsertSource: (input) => {\n const current = sourcesRef.current.get(input.id);\n if (!current) orderRef.current += 1;\n sourcesRef.current.set(\n input.id,\n mergeMediaSource(current, input, orderRef.current),\n );\n commit();\n if (!current) {\n findDisplacedAudio(\n [...sourcesRef.current.values()],\n sessionRef.current,\n input.id,\n ).forEach((entry) => entry.element?.pause());\n }\n },\n };\n }, [store]);\n\n useEffect(\n () => () => {\n bindingRef.current?.cleanup();\n bindingRef.current = null;\n },\n [],\n );\n\n const value = useMemo<MediaContextValue>(\n () => ({ actions, store }),\n [actions, store],\n );\n\n return <MediaContext value={value}>{children}</MediaContext>;\n}\n\nexport function useMediaState(): MediaState {\n const { store } = useRequiredContext(\n MediaContext,\n \"useMediaState\",\n \"MediaProvider\",\n );\n return useStore(store);\n}\n\nexport function useMediaActions(): MediaActions {\n return useRequiredContext(MediaContext, \"useMediaActions\", \"MediaProvider\")\n .actions;\n}\n\nconst NOOP_MEDIA_STORE = createStore<MediaState>(DEFAULT_MEDIA_STATE);\n\nexport function useOptionalMediaState(): MediaState;\nexport function useOptionalMediaState<T>(\n selector: (state: MediaState) => T,\n isEqual?: (a: T, b: T) => boolean,\n): T;\nexport function useOptionalMediaState<T = MediaState>(\n selector?: (state: MediaState) => T,\n isEqual?: (a: T, b: T) => boolean,\n): T {\n const ctx = useContext(MediaContext);\n return useStore(\n ctx?.store ?? NOOP_MEDIA_STORE,\n selector as (state: MediaState) => T,\n isEqual,\n );\n}\n\nexport function useOptionalMediaActions(): MediaActions {\n const ctx = useContext(MediaContext);\n return ctx?.actions ?? INERT_MEDIA_ACTIONS;\n}\n\n\n","\"use client\";\n\nimport { useCallback, useEffect, useId, useMemo, useRef } from \"react\";\nimport { useMediaActions } from \"./context\";\nimport { toggleElement } from \"./utils\";\nimport { type MediaHandle, type MediaOptions } from \"./types\";\n\nexport function useMedia(options: MediaOptions): MediaHandle {\n const generatedId = useId();\n const id = options.id ?? `media-${generatedId}`;\n const { removeSource, upsertSource } = useMediaActions();\n const audioRef = useRef<HTMLAudioElement | null>(null);\n const optionsRef = useRef(options);\n const { src, enabled = true } = options;\n const isEnabled = enabled && Boolean(src);\n\n useEffect(() => {\n optionsRef.current = options;\n });\n\n useEffect(() => {\n if (!isEnabled || !src) return undefined;\n const audio = new Audio();\n audio.preload = \"auto\";\n audio.src = src;\n audioRef.current = audio;\n\n const initial = optionsRef.current;\n audio.loop = Boolean(initial.loop);\n audio.muted = Boolean(initial.muted);\n if (typeof initial.volume === \"number\") {\n audio.volume = Math.min(1, Math.max(0, initial.volume));\n }\n\n upsertSource({\n element: audio,\n follow: initial.follow ?? null,\n id,\n isPlaying: false,\n kind: \"audio\",\n loop: audio.loop,\n });\n\n const syncPlaying = () =>\n upsertSource({ id, isPlaying: !audio.paused && !audio.ended });\n const events = [\"play\", \"playing\", \"pause\", \"ended\"] as const;\n events.forEach((type) => audio.addEventListener(type, syncPlaying));\n\n if (!initial.follow && initial.autoplay !== false) {\n void Promise.resolve(audio.play()).catch(() => {});\n }\n\n return () => {\n events.forEach((type) => audio.removeEventListener(type, syncPlaying));\n audio.pause();\n audio.removeAttribute(\"src\");\n audio.load();\n audioRef.current = null;\n removeSource(id);\n };\n }, [id, isEnabled, removeSource, src, upsertSource]);\n\n const { follow = null, loop, muted, volume } = options;\n useEffect(() => {\n const audio = audioRef.current;\n if (!audio) return;\n if (loop !== undefined && !follow) audio.loop = loop;\n if (muted !== undefined) audio.muted = muted;\n if (volume !== undefined) audio.volume = Math.min(1, Math.max(0, volume));\n upsertSource({ follow, id, ...(follow ? {} : { loop: audio.loop }) });\n }, [follow, id, isEnabled, loop, muted, src, upsertSource, volume]);\n\n const play = useCallback(() => {\n const audio = audioRef.current;\n if (audio) void Promise.resolve(audio.play()).catch(() => {});\n }, []);\n const pause = useCallback(() => audioRef.current?.pause(), []);\n const toggle = useCallback(() => toggleElement(audioRef.current), []);\n\n return useMemo(\n () => ({ id, pause, play, toggle }),\n [id, pause, play, toggle],\n );\n}\n","\"use client\";\n\nimport { useRegistryValue } from \"@/kernel\";\nimport { MEDIA_REGISTRY_KEY, PAGE_MEDIA_ID } from \"./constants\";\nimport { useMedia } from \"./hooks\";\nimport { type MediaPageOptions, type MediaSourceProps } from \"./types\";\n\n/** Declarative form of `useMedia`: mount it anywhere to register an audio source. */\nexport function MediaSource(props: MediaSourceProps) {\n useMedia(props);\n return null;\n}\n\n/**\n * Plays whatever the current page declared with `usePage({ media })`. The\n * registry drops the value when the page goes away, which stops the audio.\n */\nexport function MediaOverlay() {\n const page = useRegistryValue<\"media\", MediaPageOptions>(\n \"media\",\n MEDIA_REGISTRY_KEY,\n );\n useMedia({ ...page, id: PAGE_MEDIA_ID, src: page?.src });\n return null;\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport { defineModule, type PageModuleApi } from \"@/kernel\";\nimport { MEDIA_REGISTRY_KEY } from \"./constants\";\nimport { MediaContext, MediaProvider, useMediaActions } from \"./context\";\nimport { MediaOverlay } from \"./overlay\";\nimport { selectPageMedia } from \"./utils\";\nimport {\n type MediaPageApi,\n type MediaPageConfig,\n type MediaPageOptions,\n} from \"./types\";\n\nfunction useMediaPage(\n _slice: MediaPageOptions | null,\n page: PageModuleApi,\n): MediaPageApi {\n const actions = useMediaActions();\n return useMemo(\n () => ({\n ...actions,\n set: (media: MediaPageConfig) => page.set({ media }),\n }),\n [actions, page],\n );\n}\n\nexport const mediaModule = defineModule({\n id: \"media\",\n context: MediaContext,\n Provider: MediaProvider,\n Overlay: MediaOverlay,\n registry: {\n cleanupDelayMs: 600,\n keyPolicy: \"singleton\",\n lifecycle: \"immediate\",\n singletonKey: MEDIA_REGISTRY_KEY,\n },\n page: {\n select: (config) => selectPageMedia(config.media),\n entries: (slice: MediaPageOptions) => [\n { key: MEDIA_REGISTRY_KEY, value: slice },\n ],\n use: useMediaPage,\n },\n});\n\ndeclare module \"@omerdlw/base-framework/kernel\" {\n interface CoreModules {\n media: typeof mediaModule;\n }\n interface PageConfig {\n media?: MediaPageConfig;\n }\n}\n"]}
|
|
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/provider.tsx","../../../src/kernel/module.tsx","../../../src/modules/media/constants.ts","../../../src/modules/media/playback.ts","../../../src/modules/media/session.ts","../../../src/modules/media/context.tsx","../../../src/modules/media/hooks.ts","../../../src/modules/media/overlay.tsx","../../../src/modules/media/module.tsx"],"names":["useCallback","useSyncExternalStore","useState","useRef","useMemo","jsx","useEffect"],"mappings":";;;AAEO,SAAS,wBAAA,CACd,MACA,YAAA,EACY;AACZ,EAAA,MAAM,GAAA,mBAAM,MAAA,CAAO,GAAA,CAAI,CAAA,gCAAA,EAAmC,IAAI,CAAA,CAAE,CAAA;AAChE,EAAA,MAAM,KAAA,GAAQ,UAAA;AACd,EAAA,IAAI,CAAC,KAAA,CAAM,GAAG,CAAA,EAAG;AACf,IAAA,KAAA,CAAM,GAAG,CAAA,GAAI,aAAA,CAAiB,YAAY,CAAA;AAAA,EAC5C;AACA,EAAA,OAAO,MAAM,GAAG,CAAA;AAClB;;;ACAO,SAAS,YAAA,CAAa,GAAY,CAAA,EAAqB;AAC5D,EAAA,IAAI,MAAA,CAAO,EAAA,CAAG,CAAA,EAAG,CAAC,GAAG,OAAO,IAAA;AAC5B,EAAA,IACE,OAAO,MAAM,QAAA,IACb,CAAA,KAAM,QACN,OAAO,CAAA,KAAM,QAAA,IACb,CAAA,KAAM,IAAA,EACN;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,IAAA,CAAK,CAAW,CAAA;AACrC,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,IAAA,CAAK,CAAW,CAAA;AAErC,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,KAAA,CAAM,MAAA,EAAQ,OAAO,KAAA;AAE1C,EAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACvB,IAAA,IACE,CAAC,OAAO,SAAA,CAAU,cAAA,CAAe,KAAK,CAAA,EAAG,GAAG,CAAA,IAC5C,CAAC,MAAA,CAAO,EAAA;AAAA,MACL,EAA8B,GAAG,CAAA;AAAA,MACjC,EAA8B,GAAG;AAAA,KACpC,EACA;AACA,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;AC/BO,SAAS,MAAA,CACd,KAAA,EACA,KAAA,EACA,KAAA,GAAqB,OAAA,EACf;AAQN,EAAA,IAAI,QAAQ,GAAA,CAAI,QAAA,KAAa,YAAA,IAAgB,OAAO,WAAW,WAAA,EAAa;AAC1E,IAAA;AAAA,EACF;AACA,EAAA,OAAA,CAAQ,KAAK,CAAA,CAAE,CAAA,CAAA,EAAI,KAAK,KAAK,KAAK,CAAA;AACpC;;;ACdA,SAAS,oBAA4B,KAAA,EAAuB;AAC1D,EAAA,IACE,OAAA,CAAQ,IAAI,QAAA,KAAa,YAAA,IACzB,CAAC,KAAA,IACD,OAAO,UAAU,QAAA,EACjB;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,IAAA,uBAAW,OAAA,EAAgB;AACjC,EAAA,MAAM,MAAA,GAAS,CAAC,KAAA,KAAwB;AACtC,IAAA,IAAI,KAAK,GAAA,CAAI,KAAK,KAAK,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC/C,IAAA,IAAA,CAAK,IAAI,KAAK,CAAA;AAEd,IAAA,MAAM,SAAA,GAAY,MAAA,CAAO,cAAA,CAAe,KAAK,CAAA;AAC7C,IAAA,IACE,KAAA,CAAM,QAAQ,KAAK,CAAA,IACnB,cAAc,MAAA,CAAO,SAAA,IACrB,cAAc,IAAA,EACd;AACA,MAAA,KAAA,MAAW,GAAA,IAAO,OAAA,CAAQ,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxC,QAAA,MAAM,UAAA,GAAa,MAAA,CAAO,wBAAA,CAAyB,KAAA,EAAO,GAAG,CAAA;AAC7D,QAAA,IAAI,UAAA,IAAc,OAAA,IAAW,UAAA,IAAc,UAAA,CAAW,UAAU,IAAA,EAAM;AACpE,UAAA,IAAI,OAAO,UAAA,CAAW,KAAA,KAAU,QAAA,EAAU,MAAA,CAAO,WAAW,KAAK,CAAA;AAAA,QACnE;AAAA,MACF;AAAA,IACF;AAEA,IAAA,MAAA,CAAO,OAAO,KAAK,CAAA;AAAA,EACrB,CAAA;AAEA,EAAA,MAAA,CAAO,KAAK,CAAA;AACZ,EAAA,OAAO,KAAA;AACT;AAMO,SAAS,YACd,YAAA,EACA,EAAE,kBAAkB,IAAA,EAAK,GAAwB,EAAC,EAC3B;AACvB,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAgB;AACtC,EAAA,MAAM,OAAA,GAAU,eAAA,GACZ,mBAAA,GACA,CAAI,KAAA,KAAgB,KAAA;AACxB,EAAA,IAAI,QAAA,GAAW,QAAQ,YAAY,CAAA;AAEnC,EAAA,MAAM,OAAA,GAAU,CACd,kBAAA,KACY;AACZ,IAAA,MAAM,YACJ,OAAO,kBAAA,KAAuB,UAAA,GACzB,kBAAA,CAAwD,QAAQ,CAAA,GACjE,kBAAA;AACN,IAAA,IAAI,MAAA,CAAO,EAAA,CAAG,QAAA,EAAU,SAAS,GAAG,OAAO,KAAA;AAC3C,IAAA,QAAA,GAAW,QAAQ,SAAS,CAAA;AAE5B,IAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,MAAA,IAAI;AACF,QAAA,QAAA,EAAS;AAAA,MACX,SAAS,KAAA,EAAO;AACd,QAAA,MAAA,CAAO,sBAAA,EAAwB,OAAO,MAAM,CAAA;AAAA,MAC9C;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,QAAA,GAAW,CACf,OAAA,KACY;AACZ,IAAA,IAAI,OAAO,YAAY,UAAA,EAAY;AACjC,MAAA,OAAO,QAAQ,OAA2C,CAAA;AAAA,IAC5D;AACA,IAAA,IACE,YACA,OAAO,QAAA,KAAa,YACpB,OAAA,IACA,OAAO,YAAY,QAAA,EACnB;AACA,MAAA,OAAO,QAAQ,EAAE,GAAG,QAAA,EAAU,GAAG,SAAS,CAAA;AAAA,IAC5C;AACA,IAAA,OAAO,QAAQ,OAAiB,CAAA;AAAA,EAClC,CAAA;AAEA,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACnB,WAAA,GAAc;AACZ,MAAA,OAAO,QAAA;AAAA,IACT,CAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAU,QAAA,EAAsB;AAC9B,MAAA,IAAI,OAAO,QAAA,KAAa,UAAA,EAAY,OAAO,MAAM;AAAA,MAAC,CAAA;AAClD,MAAA,SAAA,CAAU,IAAI,QAAQ,CAAA;AACtB,MAAA,OAAO,MAAM,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AAAA,IACxC;AAAA,GACD,CAAA;AACH;AC1GO,SAAS,kBAAA,CACd,OAAA,EACA,QAAA,EACA,YAAA,EACG;AACH,EAAA,MAAM,KAAA,GAAQ,IAAI,OAAO,CAAA;AACzB,EAAA,IAAI,UAAU,IAAA,EAAM;AAClB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,EAAG,QAAQ,CAAA,qBAAA,EAAwB,YAAY,CAAA,CAAE,CAAA;AAAA,EACnE;AACA,EAAA,OAAO,KAAA;AACT;ACTO,SAAS,QAAA,CACd,OACA,QAAA,GAAsC,CAAC,UACrC,KAAA,EACF,OAAA,GAA6C,OAAO,EAAA,EAC5C;AACR,EAAA,MAAM,WAAW,MAAA,CAKd;AAAA,IACD,OAAA,EAAS,IAAA;AAAA,IACT,QAAA,EAAU,MAAA;AAAA,IACV,QAAA,EAAU,IAAA;AAAA,IACV,QAAA,EAAU;AAAA,GACX,CAAA;AAED,EAAA,MAAM,mBAAA,GAAsB,YAAY,MAAM;AAC5C,IAAA,MAAM,QAAA,GAAW,MAAM,WAAA,EAAY;AACnC,IAAA,MAAM,QAAQ,QAAA,CAAS,OAAA;AACvB,IAAA,IACE,KAAA,CAAM,aAAa,QAAA,IACnB,KAAA,CAAM,aAAa,QAAA,IACnB,KAAA,CAAM,YAAY,OAAA,EAClB;AACA,MAAA,OAAO,KAAA,CAAM,QAAA;AAAA,IACf;AAEA,IAAA,MAAM,QAAA,GAAW,SAAS,QAAQ,CAAA;AAClC,IAAA,IACE,KAAA,CAAM,QAAA,KAAa,IAAA,IACnB,KAAA,CAAM,OAAA,KAAY,WAClB,OAAA,CAAQ,KAAA,CAAM,QAAA,EAAoB,QAAQ,CAAA,EAC1C;AACA,MAAA,KAAA,CAAM,QAAA,GAAW,QAAA;AACjB,MAAA,KAAA,CAAM,QAAA,GAAW,QAAA;AACjB,MAAA,OAAO,KAAA,CAAM,QAAA;AAAA,IACf;AAEA,IAAA,QAAA,CAAS,OAAA,GAAU;AAAA,MACjB,OAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,QAAA;AAAA,EACT,CAAA,EAAG,CAAC,OAAA,EAAS,QAAA,EAAU,KAAK,CAAC,CAAA;AAE7B,EAAA,OAAO,oBAAA;AAAA,IACL,KAAA,CAAM,SAAA;AAAA,IACN,mBAAA;AAAA,IACA;AAAA,GACF;AACF;ACzBA,IAAM,eAAA,GAAkB,wBAAA;AAAA,EAEtB,iBAAA;AAAA,EACA;AACF,CAAA;AA2CA,SAAS,uBAAA,GAAgE;AACvE,EAAA,OAAO,kBAAA;AAAA,IACL,eAAA;AAAA,IACA,yBAAA;AAAA,IACA;AAAA,GACF,CAAE,YAAA;AACJ;AAEO,SAAS,gBAAA,CAGd,MAAS,GAAA,EAA4B;AACrC,EAAA,MAAM,EAAE,WAAA,EAAa,SAAA,EAAU,GAAI,uBAAA,EAAwB;AAE3D,EAAA,MAAM,cAAA,GAAiBA,WAAAA;AAAA,IACrB,CAAC,QAAA,KAAyB,SAAA,CAAU,IAAA,EAAM,KAAK,QAAQ,CAAA;AAAA,IACvD,CAAC,GAAA,EAAK,SAAA,EAAW,IAAI;AAAA,GACvB;AACA,EAAA,MAAM,QAAA,GAAWA,WAAAA;AAAA,IACf,MAAM,WAAA,CAAkB,IAAA,EAAM,GAAG,CAAA;AAAA,IACjC,CAAC,WAAA,EAAa,GAAA,EAAK,IAAI;AAAA,GACzB;AAEA,EAAA,OAAOC,oBAAAA,CAAqB,cAAA,EAAgB,QAAA,EAAU,QAAQ,CAAA;AAChE;AC9EO,SAAS,aAMd,UAAA,EACgD;AAChD,EAAA,OAAO,MAAA,CAAO,MAAA,CAAO,EAAE,GAAG,YAAY,CAAA;AACxC;AA6HgD,YAAqB,MAAS;;;AC/JvE,IAAM,mBAAA,GAAkC,OAAO,MAAA,CAAO;AAAA,EAC3D,cAAA,EAAgB,IAAA;AAAA,EAChB,OAAA,EAAS,IAAA;AAAA,EACT,QAAA,EAAU,KAAA;AAAA,EACV,SAAA,EAAW,KAAA;AAAA,EACX,IAAA,EAAM,IAAA;AAAA,EACN,IAAA,EAAM,KAAA;AAAA,EACN,QAAA,EAAU;AACZ,CAAC;AAEM,IAAM,mBAAA,GAAoC,OAAO,MAAA,CAAO;AAAA,EAC7D,cAAc,MAAM;AAAA,EAAC,CAAA;AAAA,EACrB,UAAU,MAAM;AAAA,EAAC,CAAA;AAAA,EACjB,QAAQ,MAAM;AAAA,EAAC,CAAA;AAAA,EACf,YAAY,MAAM;AAAA,EAAC,CAAA;AAAA,EACnB,cAAc,MAAM;AAAA,EAAC;AACvB,CAAC;AAGM,IAAM,wBAAA,GAA2B;AAEjC,IAAM,kBAAA,GAAqB;AAE3B,IAAM,aAAA,GAAgB;;;ACvB7B,IAAM,OAAO,MAAM;AAAC,CAAA;AAEb,SAAS,cAAc,OAAA,EAAwC;AACpE,EAAA,IAAI,CAAC,OAAA,EAAS;AACd,EAAA,IAAI,OAAA,CAAQ,MAAA,IAAU,OAAA,CAAQ,KAAA,EAAO;AACnC,IAAA,KAAK,QAAQ,OAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA,CAAE,MAAM,IAAI,CAAA;AAAA,EACjD,CAAA,MAAO;AACL,IAAA,OAAA,CAAQ,KAAA,EAAM;AAAA,EAChB;AACF;AAEO,SAAS,SAAS,OAAA,EAAiC;AACxD,EAAA,IAAI;AACF,IAAA,KAAK,QAAQ,OAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA,CAAE,MAAM,IAAI,CAAA;AAAA,EACjD,CAAA,CAAA,MAAQ;AAAA,EAAC;AACX;AAEO,SAAS,YAAA,CACd,GACA,CAAA,EACS;AACT,EAAA,OACE,CAAA,CAAE,MAAA,KAAW,CAAA,CAAE,MAAA,IAAU,CAAA,CAAE,KAAA,CAAM,CAAC,OAAA,EAAS,KAAA,KAAU,OAAA,KAAY,CAAA,CAAE,KAAK,CAAC,CAAA;AAE7E;AAEO,SAAS,aAAA,CACd,WACA,SAAA,EACY;AACZ,EAAA,MAAM,WAAW,SAAA,CAAU,GAAA,CAAI,CAAC,QAAA,KAAa,SAAS,IAAI,CAAA;AAE1D,EAAA,MAAM,KAAA,GAAQ,CAAC,IAAA,KAAkB;AAC/B,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,SAAA,CAAU,WAAW,CAAA,IAAK,CAAA;AAC9C,IAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,MAAA,QAAA,CAAS,IAAA,GAAO,KAAA;AAChB,MAAA,IAAI,QAAA,CAAS,YAAA,KAAiB,SAAA,CAAU,YAAA,EAAc;AACpD,QAAA,QAAA,CAAS,eAAe,SAAA,CAAU,YAAA;AAAA,MACpC;AACA,MAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,CAAA,CAAK,MAAA,CAAO,SAAS,WAAW,CAAA,IAAK,KAAK,IAAI,CAAA;AACjE,MAAA,IAAI,IAAA,IAAQ,KAAA,GAAQ,wBAAA,EAA0B,QAAA,CAAS,WAAA,GAAc,IAAA;AAAA,IACvE;AAAA,EACF,CAAA;AACA,EAAA,MAAM,OAAO,MAAM;AACjB,IAAA,KAAA,CAAM,KAAK,CAAA;AACX,IAAA,SAAA,CAAU,QAAQ,QAAQ,CAAA;AAAA,EAC5B,CAAA;AACA,EAAA,MAAM,KAAA,GAAQ,MAAM,SAAA,CAAU,OAAA,CAAQ,CAAC,QAAA,KAAa,QAAA,CAAS,OAAO,CAAA;AACpE,EAAA,MAAM,SAAA,GAAY,MAAM,KAAA,CAAM,IAAI,CAAA;AAClC,EAAA,MAAM,SAAA,GAAY,MAAM,KAAA,CAAM,KAAK,CAAA;AAEnC,EAAA,MAAM,SAAA,GAAoC;AAAA,IACxC,CAAC,QAAQ,IAAI,CAAA;AAAA,IACb,CAAC,WAAW,IAAI,CAAA;AAAA,IAChB,CAAC,SAAS,KAAK,CAAA;AAAA,IACf,CAAC,WAAW,KAAK,CAAA;AAAA,IACjB,CAAC,SAAS,KAAK,CAAA;AAAA,IACf,CAAC,WAAW,SAAS,CAAA;AAAA,IACrB,CAAC,UAAU,SAAS,CAAA;AAAA,IACpB,CAAC,cAAc,SAAS,CAAA;AAAA,IACxB,CAAC,cAAc,SAAS;AAAA,GAC1B;AACA,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,QAAQ,CAAA,IAAK,SAAA,EAAW;AACxC,IAAA,SAAA,CAAU,gBAAA,CAAiB,MAAM,QAAQ,CAAA;AAAA,EAC3C;AAEA,EAAA,SAAA,EAAU;AACV,EAAA,IAAI,CAAC,SAAA,CAAU,MAAA,IAAU,CAAC,SAAA,CAAU,OAAO,IAAA,EAAK;AAEhD,EAAA,OAAO,MAAM;AACX,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,QAAQ,CAAA,IAAK,SAAA,EAAW;AACxC,MAAA,SAAA,CAAU,mBAAA,CAAoB,MAAM,QAAQ,CAAA;AAAA,IAC9C;AACA,IAAA,SAAA,CAAU,OAAA,CAAQ,CAAC,QAAA,EAAU,KAAA,KAAU;AACrC,MAAA,QAAA,CAAS,IAAA,GAAO,SAAS,KAAK,CAAA;AAAA,IAChC,CAAC,CAAA;AAAA,EACH,CAAA;AACF;;;ACpEA,SAAS,OAAO,OAAA,EAA4C;AAC1D,EAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,EAAG,CAAA,KAAO,EAAE,KAAA,GAAQ,CAAA,CAAE,KAAA,GAAQ,CAAA,GAAI,CAAE,CAAA;AAC7D;AAEO,SAAS,oBACd,OAAA,EACqB;AACrB,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAEjC,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAC,MAAA,KAAW,MAAA,CAAO,EAAE,CAAC,CAAA;AACtD,EAAA,MAAM,WAAA,GAAc,CAAC,MAAA,KACnB,OAAA,CAAQ,OAAO,MAAM,CAAA,IACrB,MAAA,CAAO,MAAA,KAAW,MAAA,CAAO,EAAA,IACzB,GAAA,CAAI,GAAA,CAAI,OAAO,MAAO,CAAA;AACxB,EAAA,MAAM,UAAU,IAAI,GAAA;AAAA,IAClB,OAAA,CAAQ,MAAA,CAAO,CAAC,MAAA,KAAW,CAAC,WAAA,CAAY,MAAM,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,MAAA,KAAW,OAAO,EAAE;AAAA,GAC5E;AACA,EAAA,MAAM,UAAA,GAAa,CAAC,MAAA,KAClB,WAAA,CAAY,MAAM,CAAA,IAAK,OAAA,CAAQ,GAAA,CAAI,MAAA,CAAO,MAAO,CAAA;AAEnD,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,OAAA,CAAQ,MAAA,CAAO,CAAC,WAAW,CAAC,UAAA,CAAW,MAAM,CAAC,CAAC,CAAA;AACxE,EAAA,MAAM,SAAA,GAAY,QACf,MAAA,CAAO,CAAC,WAAW,UAAA,CAAW,MAAM,KAAK,MAAA,CAAO,MAAA,KAAW,UAAU,EAAE,CAAA,CACvE,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAK,CAAA;AACnC,EAAA,MAAM,iBAAiB,SAAA,CAAU,MAAA,CAAO,CAAC,MAAA,KAAW,MAAA,CAAO,SAAS,OAAO,CAAA;AAE3E,EAAA,OAAO;AAAA,IACL,SAAS,cAAA,CAAe,MAAA,GAAS,CAAA,GAAI,MAAA,CAAO,cAAc,CAAA,GAAI,SAAA;AAAA,IAC9D,SAAA;AAAA,IACA;AAAA,GACF;AACF;AAEO,SAAS,iBAAiB,OAAA,EAA0C;AACzE,EAAA,IAAI,CAAC,SAAS,OAAO,mBAAA;AACrB,EAAA,MAAM,EAAE,OAAA,EAAS,SAAA,EAAU,GAAI,OAAA;AAC/B,EAAA,OAAO;AAAA,IACL,gBAAgB,OAAA,CAAQ,OAAA;AAAA,IACxB,SAAS,SAAA,CAAU,OAAA;AAAA,IACnB,QAAA,EAAU,IAAA;AAAA,IACV,WAAW,SAAA,CAAU,SAAA;AAAA,IACrB,MAAM,SAAA,CAAU,IAAA;AAAA,IAChB,MAAM,SAAA,CAAU,IAAA;AAAA,IAChB,UAAU,SAAA,CAAU;AAAA,GACtB;AACF;AAEO,SAAS,gBAAA,CAAiB,GAAe,CAAA,EAAwB;AACtE,EAAA,OAAO,YAAA,CAAa,GAAG,CAAC,CAAA;AAC1B;AAEO,SAAS,gBAAA,CACd,OAAA,EACA,KAAA,EACA,KAAA,EACY;AACZ,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,MAAA;AAAA,IACV,OAAA,EAAS,IAAA;AAAA,IACT,MAAA,EAAQ,IAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,IAAA,EAAM,OAAA;AAAA,IACN,IAAA,EAAM,KAAA;AAAA,IACN,GAAG,OAAA;AAAA,IACH,GAAG,KAAA;AAAA,IACH,KAAA,EAAO,SAAS,KAAA,IAAS;AAAA,GAC3B;AACF;AAEO,SAAS,gBACd,KAAA,EACyB;AACzB,EAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,EAAE,KAAK,KAAA,EAAM;AACnD,EAAA,OAAO,KAAA,CAAM,MAAM,KAAA,GAAQ,IAAA;AAC7B;AACO,SAAS,kBAAA,CACd,OAAA,EACA,OAAA,EACA,KAAA,EACc;AACd,EAAA,IAAI,CAAC,OAAA,IAAW,OAAA,CAAQ,UAAU,EAAA,KAAO,KAAA,SAAc,EAAC;AACxD,EAAA,MAAM,WAAA,GAAc,IAAI,GAAA,CAAI,OAAA,CAAQ,SAAA,CAAU,IAAI,CAAC,KAAA,KAAU,KAAA,CAAM,EAAE,CAAC,CAAA;AACtE,EAAA,OAAO,OAAA,CAAQ,MAAA;AAAA,IACb,CAAC,KAAA,KACC,KAAA,CAAM,OAAO,KAAA,IACb,CAAC,YAAY,GAAA,CAAI,KAAA,CAAM,EAAE,CAAA,IACzB,KAAA,CAAM,SAAS,OAAA,IACf,KAAA,CAAM,YAAY,IAAA,IAClB,CAAC,MAAM,OAAA,CAAQ;AAAA,GACnB;AACF;AC3EO,IAAM,YAAA,GAAe,wBAAA;AAAA,EAC1B,cAAA;AAAA,EACA;AACF;AAEO,IAAM,gBAAA,GAAmB,YAAwB,mBAAmB;AAQpE,SAAS,aAAA,CAAc,EAAE,QAAA,EAAS,EAAuB;AAC9D,EAAA,MAAM,CAAC,KAAK,CAAA,GAAIC,QAAAA;AAAA,IAAS,MACvB,WAAA,CAAwB,mBAAA,EAAqB,EAAE,eAAA,EAAiB,OAAO;AAAA,GACzE;AACA,EAAA,MAAM,UAAA,GAAaC,MAAAA,iBAAO,IAAI,GAAA,EAAyB,CAAA;AACvD,EAAA,MAAM,UAAA,GAAaA,OAA4B,IAAI,CAAA;AACnD,EAAA,MAAM,QAAA,GAAWA,OAAO,CAAC,CAAA;AACzB,EAAA,MAAM,UAAA,GAAaA,OAAuB,IAAI,CAAA;AAE9C,EAAA,MAAM,OAAA,GAAUC,QAAsB,MAAM;AAC1C,IAAA,MAAM,SAAS,MAAM;AACnB,MAAA,UAAA,CAAW,SAAS,OAAA,EAAQ;AAC5B,MAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AAAA,IACvB,CAAA;AAEA,IAAA,MAAM,MAAA,GAAS,CAAC,OAAA,KAAiC;AAC/C,MAAA,MAAM,SAAA,GAAY,OAAA,EAAS,SAAA,CAAU,OAAA,IAAW,IAAA;AAChD,MAAA,MAAM,SAAA,GAAA,CAAa,OAAA,EAAS,SAAA,IAAa,EAAC,EAAG,GAAA;AAAA,QAC3C,CAAC,WAAW,MAAA,CAAO;AAAA,OACrB;AACA,MAAA,MAAM,UAAU,UAAA,CAAW,OAAA;AAC3B,MAAA,IACE,OAAA,IACA,QAAQ,SAAA,KAAc,SAAA,IACtB,aAAa,OAAA,CAAQ,SAAA,EAAW,SAAS,CAAA,EACzC;AACA,QAAA;AAAA,MACF;AACA,MAAA,MAAA,EAAO;AACP,MAAA,MAAM,OAAO,SAAA,CAAU,MAAA;AAAA,QACrB,CAAC,YAAyC,OAAA,KAAY;AAAA,OACxD;AACA,MAAA,IAAI,CAAC,SAAA,IAAa,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG;AACrC,MAAA,UAAA,CAAW,OAAA,GAAU;AAAA,QACnB,OAAA,EAAS,aAAA,CAAc,SAAA,EAAW,IAAI,CAAA;AAAA,QACtC,SAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,SAAS,MAAM;AACnB,MAAA,MAAM,OAAA,GAAU,oBAAoB,CAAC,GAAG,WAAW,OAAA,CAAQ,MAAA,EAAQ,CAAC,CAAA;AACpE,MAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AACrB,MAAA,MAAA,CAAO,OAAO,CAAA;AACd,MAAA,MAAM,IAAA,GAAO,iBAAiB,OAAO,CAAA;AACrC,MAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,IAAA,KAAU,gBAAA,CAAiB,MAAM,IAAI,CAAA,GAAI,OAAO,IAAK,CAAA;AAAA,IACtE,CAAA;AAEA,IAAA,MAAM,KAAA,GAAQ,CAAC,EAAA,EAAY,OAAA,KAAiC;AAC1D,MAAA,MAAM,OAAA,GAAU,UAAA,CAAW,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA;AACzC,MAAA,IAAI,CAAC,OAAA,EAAS;AACd,MAAA,UAAA,CAAW,OAAA,CAAQ,IAAI,EAAA,EAAI,EAAE,GAAG,OAAA,EAAS,GAAG,SAAS,CAAA;AACrD,MAAA,MAAA,EAAO;AAAA,IACT,CAAA;AAEA,IAAA,OAAO;AAAA,MACL,YAAA,EAAc,CAAC,EAAA,KAAO;AACpB,QAAA,IAAI,UAAA,CAAW,OAAA,CAAQ,MAAA,CAAO,EAAE,GAAG,MAAA,EAAO;AAAA,MAC5C,CAAA;AAAA,MACA,QAAA,EAAU,CAAC,KAAA,KAAU;AACnB,QAAA,MAAM,OAAA,GAAU,WAAW,OAAA,EAAS,OAAA;AACpC,QAAA,IAAI,CAAC,OAAA,EAAS;AACd,QAAA,IAAI,QAAQ,QAAA,EAAU,QAAA,EAAU,OAAA,CAAQ,QAAA,CAAS,SAAS,KAAK,CAAA;AAAA,aAAA,IACtD,OAAA,CAAQ,OAAA,EAAS,OAAA,CAAQ,OAAA,CAAQ,KAAA,GAAQ,KAAA;AAAA,MACpD,CAAA;AAAA,MACA,QAAQ,MAAM;AACZ,QAAA,MAAM,SAAA,GAAY,WAAW,OAAA,EAAS,SAAA;AACtC,QAAA,IAAI,CAAC,SAAA,EAAW;AAChB,QAAA,IAAI,SAAA,CAAU,QAAA,EAAU,MAAA,EAAQ,SAAA,CAAU,SAAS,MAAA,EAAO;AAAA,aACrD,aAAA,CAAc,UAAU,OAAO,CAAA;AAAA,MACtC,CAAA;AAAA,MACA,YAAY,MAAM;AAChB,QAAA,MAAM,SAAA,GAAY,WAAW,OAAA,EAAS,SAAA;AACtC,QAAA,IAAI,CAAC,SAAA,EAAW;AAChB,QAAA,IAAI,SAAA,CAAU,UAAU,UAAA,EAAY;AAClC,UAAA,SAAA,CAAU,SAAS,UAAA,EAAW;AAC9B,UAAA;AAAA,QACF;AACA,QAAA,MAAM,IAAA,GAAO,CAAC,SAAA,CAAU,IAAA;AACxB,QAAA,IAAI,SAAA,CAAU,OAAA,EAAS,SAAA,CAAU,OAAA,CAAQ,IAAA,GAAO,IAAA;AAChD,QAAA,KAAA,CAAM,SAAA,CAAU,EAAA,EAAI,EAAE,IAAA,EAAM,CAAA;AAAA,MAC9B,CAAA;AAAA,MACA,YAAA,EAAc,CAAC,KAAA,KAAU;AACvB,QAAA,MAAM,OAAA,GAAU,UAAA,CAAW,OAAA,CAAQ,GAAA,CAAI,MAAM,EAAE,CAAA;AAC/C,QAAA,IAAI,CAAC,OAAA,EAAS,QAAA,CAAS,OAAA,IAAW,CAAA;AAClC,QAAA,UAAA,CAAW,OAAA,CAAQ,GAAA;AAAA,UACjB,KAAA,CAAM,EAAA;AAAA,UACN,gBAAA,CAAiB,OAAA,EAAS,KAAA,EAAO,QAAA,CAAS,OAAO;AAAA,SACnD;AACA,QAAA,MAAA,EAAO;AACP,QAAA,IAAI,CAAC,OAAA,EAAS;AACZ,UAAA,kBAAA;AAAA,YACE,CAAC,GAAG,UAAA,CAAW,OAAA,CAAQ,QAAQ,CAAA;AAAA,YAC/B,UAAA,CAAW,OAAA;AAAA,YACX,KAAA,CAAM;AAAA,YACN,OAAA,CAAQ,CAAC,UAAU,KAAA,CAAM,OAAA,EAAS,OAAO,CAAA;AAAA,QAC7C;AAAA,MACF;AAAA,KACF;AAAA,EACF,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,SAAA;AAAA,IACE,MAAM,MAAM;AACV,MAAA,UAAA,CAAW,SAAS,OAAA,EAAQ;AAC5B,MAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AAAA,IACvB,CAAA;AAAA,IACA;AAAC,GACH;AAEA,EAAA,MAAM,KAAA,GAAQA,OAAAA;AAAA,IACZ,OAAO,EAAE,OAAA,EAAS,KAAA,EAAM,CAAA;AAAA,IACxB,CAAC,SAAS,KAAK;AAAA,GACjB;AAEA,EAAA,uBAAOC,GAAAA,CAAC,YAAA,EAAA,EAAa,KAAA,EAAe,QAAA,EAAS,CAAA;AAC/C;ACtIO,SAAS,aAAA,GAA4B;AAC1C,EAAA,MAAM,EAAE,OAAM,GAAI,kBAAA;AAAA,IAChB,YAAA;AAAA,IACA,eAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,OAAO,SAAS,KAAK,CAAA;AACvB;AAEO,SAAS,eAAA,GAAgC;AAC9C,EAAA,OAAO,kBAAA,CAAmB,YAAA,EAAc,iBAAA,EAAmB,eAAe,CAAA,CACvE,OAAA;AACL;AAOO,SAAS,qBAAA,CACd,UACA,OAAA,EACG;AACH,EAAA,MAAM,GAAA,GAAM,WAAW,YAAY,CAAA;AACnC,EAAA,OAAO,QAAA;AAAA,IACL,KAAK,KAAA,IAAS,gBAAA;AAAA,IACd,QAAA;AAAA,IACA;AAAA,GACF;AACF;AAEO,SAAS,uBAAA,GAAwC;AACtD,EAAA,MAAM,GAAA,GAAM,WAAW,YAAY,CAAA;AACnC,EAAA,OAAO,KAAK,OAAA,IAAW,mBAAA;AACzB;AAEO,SAAS,SAAS,OAAA,EAAoC;AAC3D,EAAA,MAAM,cAAc,KAAA,EAAM;AAC1B,EAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,EAAA,IAAM,CAAA,MAAA,EAAS,WAAW,CAAA,CAAA;AAC7C,EAAA,MAAM,EAAE,YAAA,EAAc,YAAA,EAAa,GAAI,eAAA,EAAgB;AACvD,EAAA,MAAM,QAAA,GAAWF,OAAgC,IAAI,CAAA;AACrD,EAAA,MAAM,UAAA,GAAaA,OAAO,OAAO,CAAA;AACjC,EAAA,MAAM,EAAE,GAAA,EAAK,OAAA,GAAU,IAAA,EAAK,GAAI,OAAA;AAChC,EAAA,MAAM,SAAA,GAAY,OAAA,IAAW,OAAA,CAAQ,GAAG,CAAA;AAExC,EAAAG,UAAU,MAAM;AACd,IAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AAAA,EACvB,CAAC,CAAA;AAED,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,SAAA,IAAa,CAAC,GAAA,EAAK,OAAO,MAAA;AAC/B,IAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,EAAM;AACxB,IAAA,KAAA,CAAM,OAAA,GAAU,MAAA;AAChB,IAAA,KAAA,CAAM,GAAA,GAAM,GAAA;AACZ,IAAA,QAAA,CAAS,OAAA,GAAU,KAAA;AAEnB,IAAA,MAAM,UAAU,UAAA,CAAW,OAAA;AAC3B,IAAA,KAAA,CAAM,IAAA,GAAO,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA;AACjC,IAAA,KAAA,CAAM,KAAA,GAAQ,OAAA,CAAQ,OAAA,CAAQ,KAAK,CAAA;AACnC,IAAA,IAAI,OAAO,OAAA,CAAQ,MAAA,KAAW,QAAA,EAAU;AACtC,MAAA,KAAA,CAAM,MAAA,GAAS,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,OAAA,CAAQ,MAAM,CAAC,CAAA;AAAA,IACxD;AAEA,IAAA,YAAA,CAAa;AAAA,MACX,OAAA,EAAS,KAAA;AAAA,MACT,MAAA,EAAQ,QAAQ,MAAA,IAAU,IAAA;AAAA,MAC1B,EAAA;AAAA,MACA,SAAA,EAAW,KAAA;AAAA,MACX,IAAA,EAAM,OAAA;AAAA,MACN,MAAM,KAAA,CAAM;AAAA,KACb,CAAA;AAED,IAAA,MAAM,WAAA,GAAc,MAClB,YAAA,CAAa,EAAE,EAAA,EAAI,SAAA,EAAW,CAAC,KAAA,CAAM,MAAA,IAAU,CAAC,KAAA,CAAM,KAAA,EAAO,CAAA;AAC/D,IAAA,MAAM,MAAA,GAAS,CAAC,MAAA,EAAQ,SAAA,EAAW,SAAS,OAAO,CAAA;AACnD,IAAA,MAAA,CAAO,QAAQ,CAAC,IAAA,KAAS,MAAM,gBAAA,CAAiB,IAAA,EAAM,WAAW,CAAC,CAAA;AAElE,IAAA,IAAI,CAAC,OAAA,CAAQ,MAAA,IAAU,OAAA,CAAQ,aAAa,KAAA,EAAO;AACjD,MAAA,KAAK,QAAQ,OAAA,CAAQ,KAAA,CAAM,MAAM,CAAA,CAAE,MAAM,MAAM;AAAA,MAAC,CAAC,CAAA;AAAA,IACnD;AAEA,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,QAAQ,CAAC,IAAA,KAAS,MAAM,mBAAA,CAAoB,IAAA,EAAM,WAAW,CAAC,CAAA;AACrE,MAAA,KAAA,CAAM,KAAA,EAAM;AACZ,MAAA,KAAA,CAAM,gBAAgB,KAAK,CAAA;AAC3B,MAAA,KAAA,CAAM,IAAA,EAAK;AACX,MAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AACnB,MAAA,YAAA,CAAa,EAAE,CAAA;AAAA,IACjB,CAAA;AAAA,EACF,GAAG,CAAC,EAAA,EAAI,WAAW,YAAA,EAAc,GAAA,EAAK,YAAY,CAAC,CAAA;AAEnD,EAAA,MAAM,EAAE,MAAA,GAAS,IAAA,EAAM,IAAA,EAAM,KAAA,EAAO,QAAO,GAAI,OAAA;AAC/C,EAAAA,UAAU,MAAM;AACd,IAAA,MAAM,QAAQ,QAAA,CAAS,OAAA;AACvB,IAAA,IAAI,CAAC,KAAA,EAAO;AACZ,IAAA,IAAI,IAAA,KAAS,MAAA,IAAa,CAAC,MAAA,QAAc,IAAA,GAAO,IAAA;AAChD,IAAA,IAAI,KAAA,KAAU,MAAA,EAAW,KAAA,CAAM,KAAA,GAAQ,KAAA;AACvC,IAAA,IAAI,MAAA,KAAW,MAAA,EAAW,KAAA,CAAM,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAM,CAAC,CAAA;AACxE,IAAA,YAAA,CAAa,EAAE,MAAA,EAAQ,EAAA,EAAI,GAAI,MAAA,GAAS,EAAC,GAAI,EAAE,IAAA,EAAM,KAAA,CAAM,IAAA,EAAK,EAAI,CAAA;AAAA,EACtE,CAAA,EAAG,CAAC,MAAA,EAAQ,EAAA,EAAI,SAAA,EAAW,MAAM,KAAA,EAAO,GAAA,EAAK,YAAA,EAAc,MAAM,CAAC,CAAA;AAElE,EAAA,MAAM,IAAA,GAAON,YAAY,MAAM;AAC7B,IAAA,MAAM,QAAQ,QAAA,CAAS,OAAA;AACvB,IAAA,IAAI,KAAA,OAAY,OAAA,CAAQ,OAAA,CAAQ,MAAM,IAAA,EAAM,CAAA,CAAE,KAAA,CAAM,MAAM;AAAA,IAAC,CAAC,CAAA;AAAA,EAC9D,CAAA,EAAG,EAAE,CAAA;AACL,EAAA,MAAM,KAAA,GAAQA,YAAY,MAAM,QAAA,CAAS,SAAS,KAAA,EAAM,EAAG,EAAE,CAAA;AAC7D,EAAA,MAAM,MAAA,GAASA,YAAY,MAAM,aAAA,CAAc,SAAS,OAAO,CAAA,EAAG,EAAE,CAAA;AAEpE,EAAA,OAAOI,OAAAA;AAAA,IACL,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAM,MAAA,EAAO,CAAA;AAAA,IACjC,CAAC,EAAA,EAAI,KAAA,EAAO,IAAA,EAAM,MAAM;AAAA,GAC1B;AACF;;;AC9HO,SAAS,YAAY,KAAA,EAAyB;AACnD,EAAA,QAAA,CAAS,KAAK,CAAA;AACd,EAAA,OAAO,IAAA;AACT;AAEO,SAAS,YAAA,GAAe;AAC7B,EAAA,MAAM,IAAA,GAAO,gBAAA;AAAA,IACX,OAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,QAAA,CAAS,EAAE,GAAG,IAAA,EAAM,EAAA,EAAI,eAAe,GAAA,EAAK,IAAA,EAAM,KAAK,CAAA;AACvD,EAAA,OAAO,IAAA;AACT;;;ACJA,SAAS,YAAA,CACP,QACA,IAAA,EACc;AACd,EAAA,MAAM,UAAU,eAAA,EAAgB;AAChC,EAAA,OAAOA,OAAAA;AAAA,IACL,OAAO;AAAA,MACL,GAAG,OAAA;AAAA,MACH,KAAK,CAAC,KAAA,KAA2B,KAAK,GAAA,CAAI,EAAE,OAAO;AAAA,KACrD,CAAA;AAAA,IACA,CAAC,SAAS,IAAI;AAAA,GAChB;AACF;AAEO,IAAM,cAAc,YAAA,CAAa;AAAA,EACtC,EAAA,EAAI,OAAA;AAAA,EACJ,OAAA,EAAS,YAAA;AAAA,EACT,QAAA,EAAU,aAAA;AAAA,EACV,OAAA,EAAS,YAAA;AAAA,EACT,QAAA,EAAU;AAAA,IACR,cAAA,EAAgB,GAAA;AAAA,IAChB,SAAA,EAAW,WAAA;AAAA,IACX,SAAA,EAAW,WAAA;AAAA,IACX,YAAA,EAAc;AAAA,GAChB;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,MAAA,EAAQ,CAAC,MAAA,KAAW,eAAA,CAAgB,OAAO,KAAK,CAAA;AAAA,IAChD,OAAA,EAAS,CAAC,KAAA,KAA4B;AAAA,MACpC,EAAE,GAAA,EAAK,kBAAA,EAAoB,KAAA,EAAO,KAAA;AAAM,KAC1C;AAAA,IACA,GAAA,EAAK;AAAA;AAET,CAAC","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 {\n useCallback,\n useMemo,\n useState,\n useSyncExternalStore,\n type ReactNode,\n} from \"react\";\nimport { useRequiredContext } from \"@/hooks\";\nimport { getOrCreateGlobalContext } from \"./context-registry\";\n\nimport type {\n RegistryDefinitions,\n RegistrySchema,\n RegistryStore,\n} from \"./types\";\nimport { createRegistryStore, type InitialRegistryEntries } from \"./store\";\n\ntype RegistryValueOf<K extends string> = K extends keyof RegistrySchema\n ? RegistrySchema[K]\n : unknown;\n\ninterface RegistryContextValue {\n actions: Pick<\n RegistryStore,\n \"batch\" | \"register\" | \"transaction\" | \"unregister\"\n >;\n subscription: Pick<\n RegistryStore,\n \"getEntriesSnapshot\" | \"getSnapshot\" | \"subscribe\"\n >;\n}\n\nconst RegistryContext = getOrCreateGlobalContext<RegistryContextValue | null>(\n\n \"RegistryContext\",\n null,\n);\n\nexport function RegistryProvider({\n children,\n definitions,\n initialEntries = [],\n}: {\n children?: ReactNode;\n definitions?: RegistryDefinitions;\n initialEntries?: InitialRegistryEntries;\n}) {\n const [store] = useState(() =>\n createRegistryStore(initialEntries, definitions),\n );\n\n const contextValue = useMemo(\n () => ({\n actions: {\n batch: store.batch,\n register: store.register,\n transaction: store.transaction,\n unregister: store.unregister,\n },\n subscription: {\n getEntriesSnapshot: store.getEntriesSnapshot,\n getSnapshot: store.getSnapshot,\n subscribe: store.subscribe,\n },\n }),\n [store],\n );\n\n return <RegistryContext value={contextValue}>{children}</RegistryContext>;\n}\n\nexport function useRegistryActions(): RegistryContextValue[\"actions\"] {\n return useRequiredContext(\n RegistryContext,\n \"useRegistryActions\",\n \"RegistryProvider\",\n ).actions;\n}\n\nfunction useRegistrySubscription(): RegistryContextValue[\"subscription\"] {\n return useRequiredContext(\n RegistryContext,\n \"useRegistrySubscription\",\n \"RegistryProvider\",\n ).subscription;\n}\n\nexport function useRegistryValue<\n K extends string = string,\n T = RegistryValueOf<K>,\n>(type: K, key: string): T | undefined {\n const { getSnapshot, subscribe } = useRegistrySubscription();\n\n const subscribeToKey = useCallback(\n (listener: () => void) => subscribe(type, key, listener),\n [key, subscribe, type],\n );\n const getValue = useCallback(\n () => getSnapshot<K, T>(type, key),\n [getSnapshot, key, type],\n );\n\n return useSyncExternalStore(subscribeToKey, getValue, getValue);\n}\n\nexport function useRegistryEntries<\n K extends string = string,\n T = RegistryValueOf<K>,\n>(type: K): Record<string, T> {\n const { getEntriesSnapshot, subscribe } = useRegistrySubscription();\n\n const subscribeToType = useCallback(\n (listener: () => void) => subscribe(type, null, listener),\n [subscribe, type],\n );\n const getEntries = useCallback(\n () => getEntriesSnapshot<K, T>(type),\n [getEntriesSnapshot, type],\n );\n\n return useSyncExternalStore(subscribeToType, getEntries, getEntries);\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","import { type MediaActions, type MediaState } from \"./types\";\n\nexport const DEFAULT_MEDIA_STATE: MediaState = Object.freeze({\n audibleElement: null,\n element: null,\n hasMedia: false,\n isPlaying: false,\n kind: null,\n loop: false,\n sourceId: null,\n});\n\nexport const INERT_MEDIA_ACTIONS: MediaActions = Object.freeze({\n removeSource: () => {},\n setMuted: () => {},\n toggle: () => {},\n toggleLoop: () => {},\n upsertSource: () => {},\n});\n\n\nexport const MEDIA_SYNC_DRIFT_SECONDS = 0.3;\n\nexport const MEDIA_REGISTRY_KEY = \"page-media\";\n\nexport const PAGE_MEDIA_ID = \"page\";\n","import { MEDIA_SYNC_DRIFT_SECONDS } from \"./constants\";\n\nconst noop = () => {};\n\nexport function toggleElement(element: HTMLMediaElement | null): void {\n if (!element) return;\n if (element.paused || element.ended) {\n void Promise.resolve(element.play()).catch(noop);\n } else {\n element.pause();\n }\n}\n\nexport function safePlay(element: HTMLMediaElement): void {\n try {\n void Promise.resolve(element.play()).catch(noop);\n } catch {}\n}\n\nexport function sameElements(\n a: readonly (HTMLMediaElement | null)[],\n b: readonly (HTMLMediaElement | null)[],\n): boolean {\n return (\n a.length === b.length && a.every((element, index) => element === b[index])\n );\n}\n\nexport function bindFollowers(\n transport: HTMLMediaElement,\n followers: readonly HTMLMediaElement[],\n): () => void {\n const ownLoops = followers.map((follower) => follower.loop);\n\n const align = (hard: boolean) => {\n const time = Number(transport.currentTime) || 0;\n for (const follower of followers) {\n follower.loop = false;\n if (follower.playbackRate !== transport.playbackRate) {\n follower.playbackRate = transport.playbackRate;\n }\n const drift = Math.abs((Number(follower.currentTime) || 0) - time);\n if (hard || drift > MEDIA_SYNC_DRIFT_SECONDS) follower.currentTime = time;\n }\n };\n const play = () => {\n align(false);\n followers.forEach(safePlay);\n };\n const pause = () => followers.forEach((follower) => follower.pause());\n const hardAlign = () => align(true);\n const softAlign = () => align(false);\n\n const listeners: [string, () => void][] = [\n [\"play\", play],\n [\"playing\", play],\n [\"pause\", pause],\n [\"waiting\", pause],\n [\"ended\", pause],\n [\"seeking\", hardAlign],\n [\"seeked\", hardAlign],\n [\"ratechange\", softAlign],\n [\"timeupdate\", softAlign],\n ];\n for (const [type, listener] of listeners) {\n transport.addEventListener(type, listener);\n }\n\n hardAlign();\n if (!transport.paused && !transport.ended) play();\n\n return () => {\n for (const [type, listener] of listeners) {\n transport.removeEventListener(type, listener);\n }\n followers.forEach((follower, index) => {\n follower.loop = ownLoops[index];\n });\n };\n}\n","import { shallowEqual } from \"@/utils\";\nimport { DEFAULT_MEDIA_STATE } from \"./constants\";\nimport {\n type MediaEntry,\n type MediaEntryInput,\n type MediaPageConfig,\n type MediaPageOptions,\n type MediaSession,\n type MediaState,\n} from \"./types\";\n\nfunction newest(sources: readonly MediaEntry[]): MediaEntry {\n return sources.reduce((a, b) => (b.order > a.order ? b : a));\n}\n\nexport function resolveMediaSession(\n sources: readonly MediaEntry[],\n): MediaSession | null {\n if (sources.length === 0) return null;\n\n const ids = new Set(sources.map((source) => source.id));\n const wantsFollow = (source: MediaEntry) =>\n Boolean(source.follow) &&\n source.follow !== source.id &&\n ids.has(source.follow!);\n const rootIds = new Set(\n sources.filter((source) => !wantsFollow(source)).map((source) => source.id),\n );\n const isFollower = (source: MediaEntry) =>\n wantsFollow(source) && rootIds.has(source.follow!);\n\n const transport = newest(sources.filter((source) => !isFollower(source)));\n const followers = sources\n .filter((source) => isFollower(source) && source.follow === transport.id)\n .sort((a, b) => a.order - b.order);\n const audioFollowers = followers.filter((source) => source.kind === \"audio\");\n\n return {\n audible: audioFollowers.length > 0 ? newest(audioFollowers) : transport,\n followers,\n transport,\n };\n}\n\nexport function createMediaState(session: MediaSession | null): MediaState {\n if (!session) return DEFAULT_MEDIA_STATE;\n const { audible, transport } = session;\n return {\n audibleElement: audible.element,\n element: transport.element,\n hasMedia: true,\n isPlaying: transport.isPlaying,\n kind: transport.kind,\n loop: transport.loop,\n sourceId: transport.id,\n };\n}\n\nexport function mediaStatesEqual(a: MediaState, b: MediaState): boolean {\n return shallowEqual(a, b);\n}\n\nexport function mergeMediaSource(\n current: MediaEntry | undefined,\n input: MediaEntryInput,\n order: number,\n): MediaEntry {\n return {\n controls: undefined,\n element: null,\n follow: null,\n isPlaying: false,\n kind: \"audio\",\n loop: false,\n ...current,\n ...input,\n order: current?.order ?? order,\n };\n}\n\nexport function selectPageMedia(\n media: MediaPageConfig | null | undefined,\n): MediaPageOptions | null {\n if (!media) return null;\n if (typeof media === \"string\") return { src: media };\n return media.src ? media : null;\n}\nexport function findDisplacedAudio(\n entries: readonly MediaEntry[],\n session: MediaSession | null,\n newId: string,\n): MediaEntry[] {\n if (!session || session.transport.id !== newId) return [];\n const followerIds = new Set(session.followers.map((entry) => entry.id));\n return entries.filter(\n (entry) =>\n entry.id !== newId &&\n !followerIds.has(entry.id) &&\n entry.kind === \"audio\" &&\n entry.element !== null &&\n !entry.element.paused,\n );\n}\n","\"use client\";\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { getOrCreateGlobalContext } from \"@/kernel\";\nimport { createStore } from \"@/utils\";\nimport { DEFAULT_MEDIA_STATE } from \"./constants\";\nimport {\n bindFollowers,\n sameElements,\n toggleElement,\n} from \"./playback\";\nimport {\n createMediaState,\n findDisplacedAudio,\n mediaStatesEqual,\n mergeMediaSource,\n resolveMediaSession,\n} from \"./session\";\nimport {\n type MediaActions,\n type MediaContextValue,\n type MediaEntry,\n type MediaProviderProps,\n type MediaSession,\n type MediaState,\n} from \"./types\";\n\nexport const MediaContext = getOrCreateGlobalContext<MediaContextValue | null>(\n \"MediaContext\",\n null,\n);\n\nexport const NOOP_MEDIA_STORE = createStore<MediaState>(DEFAULT_MEDIA_STATE);\n\ninterface Binding {\n cleanup: () => void;\n followers: readonly (HTMLMediaElement | null)[];\n transport: HTMLMediaElement;\n}\n\nexport function MediaProvider({ children }: MediaProviderProps) {\n const [store] = useState(() =>\n createStore<MediaState>(DEFAULT_MEDIA_STATE, { freezeSnapshots: false }),\n );\n const sourcesRef = useRef(new Map<string, MediaEntry>());\n const sessionRef = useRef<MediaSession | null>(null);\n const orderRef = useRef(0);\n const bindingRef = useRef<Binding | null>(null);\n\n const actions = useMemo<MediaActions>(() => {\n const unbind = () => {\n bindingRef.current?.cleanup();\n bindingRef.current = null;\n };\n\n const rebind = (session: MediaSession | null) => {\n const transport = session?.transport.element ?? null;\n const followers = (session?.followers ?? []).map(\n (source) => source.element,\n );\n const current = bindingRef.current;\n if (\n current &&\n current.transport === transport &&\n sameElements(current.followers, followers)\n ) {\n return;\n }\n unbind();\n const live = followers.filter(\n (element): element is HTMLMediaElement => element !== null,\n );\n if (!transport || live.length === 0) return;\n bindingRef.current = {\n cleanup: bindFollowers(transport, live),\n followers,\n transport,\n };\n };\n\n const commit = () => {\n const session = resolveMediaSession([...sourcesRef.current.values()]);\n sessionRef.current = session;\n rebind(session);\n const next = createMediaState(session);\n store.publish((prev) => (mediaStatesEqual(prev, next) ? prev : next));\n };\n\n const patch = (id: string, changes: Partial<MediaEntry>) => {\n const current = sourcesRef.current.get(id);\n if (!current) return;\n sourcesRef.current.set(id, { ...current, ...changes });\n commit();\n };\n\n return {\n removeSource: (id) => {\n if (sourcesRef.current.delete(id)) commit();\n },\n setMuted: (muted) => {\n const audible = sessionRef.current?.audible;\n if (!audible) return;\n if (audible.controls?.setMuted) audible.controls.setMuted(muted);\n else if (audible.element) audible.element.muted = muted;\n },\n toggle: () => {\n const transport = sessionRef.current?.transport;\n if (!transport) return;\n if (transport.controls?.toggle) transport.controls.toggle();\n else toggleElement(transport.element);\n },\n toggleLoop: () => {\n const transport = sessionRef.current?.transport;\n if (!transport) return;\n if (transport.controls?.toggleLoop) {\n transport.controls.toggleLoop();\n return;\n }\n const loop = !transport.loop;\n if (transport.element) transport.element.loop = loop;\n patch(transport.id, { loop });\n },\n upsertSource: (input) => {\n const current = sourcesRef.current.get(input.id);\n if (!current) orderRef.current += 1;\n sourcesRef.current.set(\n input.id,\n mergeMediaSource(current, input, orderRef.current),\n );\n commit();\n if (!current) {\n findDisplacedAudio(\n [...sourcesRef.current.values()],\n sessionRef.current,\n input.id,\n ).forEach((entry) => entry.element?.pause());\n }\n },\n };\n }, [store]);\n\n useEffect(\n () => () => {\n bindingRef.current?.cleanup();\n bindingRef.current = null;\n },\n [],\n );\n\n const value = useMemo<MediaContextValue>(\n () => ({ actions, store }),\n [actions, store],\n );\n\n return <MediaContext value={value}>{children}</MediaContext>;\n}\n","\"use client\";\n\nimport {\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n} from \"react\";\nimport { useRequiredContext, useStore } from \"@/hooks\";\nimport { INERT_MEDIA_ACTIONS } from \"./constants\";\nimport { MediaContext, NOOP_MEDIA_STORE } from \"./context\";\nimport { toggleElement } from \"./playback\";\nimport {\n type MediaActions,\n type MediaHandle,\n type MediaOptions,\n type MediaState,\n} from \"./types\";\n\nexport function useMediaState(): MediaState {\n const { store } = useRequiredContext(\n MediaContext,\n \"useMediaState\",\n \"MediaProvider\",\n );\n return useStore(store);\n}\n\nexport function useMediaActions(): MediaActions {\n return useRequiredContext(MediaContext, \"useMediaActions\", \"MediaProvider\")\n .actions;\n}\n\nexport function useOptionalMediaState(): MediaState;\nexport function useOptionalMediaState<T>(\n selector: (state: MediaState) => T,\n isEqual?: (a: T, b: T) => boolean,\n): T;\nexport function useOptionalMediaState<T = MediaState>(\n selector?: (state: MediaState) => T,\n isEqual?: (a: T, b: T) => boolean,\n): T {\n const ctx = useContext(MediaContext);\n return useStore(\n ctx?.store ?? NOOP_MEDIA_STORE,\n selector as (state: MediaState) => T,\n isEqual,\n );\n}\n\nexport function useOptionalMediaActions(): MediaActions {\n const ctx = useContext(MediaContext);\n return ctx?.actions ?? INERT_MEDIA_ACTIONS;\n}\n\nexport function useMedia(options: MediaOptions): MediaHandle {\n const generatedId = useId();\n const id = options.id ?? `media-${generatedId}`;\n const { removeSource, upsertSource } = useMediaActions();\n const audioRef = useRef<HTMLAudioElement | null>(null);\n const optionsRef = useRef(options);\n const { src, enabled = true } = options;\n const isEnabled = enabled && Boolean(src);\n\n useEffect(() => {\n optionsRef.current = options;\n });\n\n useEffect(() => {\n if (!isEnabled || !src) return undefined;\n const audio = new Audio();\n audio.preload = \"auto\";\n audio.src = src;\n audioRef.current = audio;\n\n const initial = optionsRef.current;\n audio.loop = Boolean(initial.loop);\n audio.muted = Boolean(initial.muted);\n if (typeof initial.volume === \"number\") {\n audio.volume = Math.min(1, Math.max(0, initial.volume));\n }\n\n upsertSource({\n element: audio,\n follow: initial.follow ?? null,\n id,\n isPlaying: false,\n kind: \"audio\",\n loop: audio.loop,\n });\n\n const syncPlaying = () =>\n upsertSource({ id, isPlaying: !audio.paused && !audio.ended });\n const events = [\"play\", \"playing\", \"pause\", \"ended\"] as const;\n events.forEach((type) => audio.addEventListener(type, syncPlaying));\n\n if (!initial.follow && initial.autoplay !== false) {\n void Promise.resolve(audio.play()).catch(() => {});\n }\n\n return () => {\n events.forEach((type) => audio.removeEventListener(type, syncPlaying));\n audio.pause();\n audio.removeAttribute(\"src\");\n audio.load();\n audioRef.current = null;\n removeSource(id);\n };\n }, [id, isEnabled, removeSource, src, upsertSource]);\n\n const { follow = null, loop, muted, volume } = options;\n useEffect(() => {\n const audio = audioRef.current;\n if (!audio) return;\n if (loop !== undefined && !follow) audio.loop = loop;\n if (muted !== undefined) audio.muted = muted;\n if (volume !== undefined) audio.volume = Math.min(1, Math.max(0, volume));\n upsertSource({ follow, id, ...(follow ? {} : { loop: audio.loop }) });\n }, [follow, id, isEnabled, loop, muted, src, upsertSource, volume]);\n\n const play = useCallback(() => {\n const audio = audioRef.current;\n if (audio) void Promise.resolve(audio.play()).catch(() => {});\n }, []);\n const pause = useCallback(() => audioRef.current?.pause(), []);\n const toggle = useCallback(() => toggleElement(audioRef.current), []);\n\n return useMemo(\n () => ({ id, pause, play, toggle }),\n [id, pause, play, toggle],\n );\n}\n","\"use client\";\n\nimport { useRegistryValue } from \"@/kernel\";\nimport { MEDIA_REGISTRY_KEY, PAGE_MEDIA_ID } from \"./constants\";\nimport { useMedia } from \"./hooks\";\nimport { type MediaPageOptions, type MediaSourceProps } from \"./types\";\n\nexport function MediaSource(props: MediaSourceProps) {\n useMedia(props);\n return null;\n}\n\nexport function MediaOverlay() {\n const page = useRegistryValue<\"media\", MediaPageOptions>(\n \"media\",\n MEDIA_REGISTRY_KEY,\n );\n useMedia({ ...page, id: PAGE_MEDIA_ID, src: page?.src });\n return null;\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport { defineModule, type PageModuleApi } from \"@/kernel\";\nimport { MEDIA_REGISTRY_KEY } from \"./constants\";\nimport { MediaContext, MediaProvider } from \"./context\";\nimport { useMediaActions } from \"./hooks\";\nimport { MediaOverlay } from \"./overlay\";\nimport { selectPageMedia } from \"./session\";\nimport {\n type MediaPageApi,\n type MediaPageConfig,\n type MediaPageOptions,\n} from \"./types\";\n\nfunction useMediaPage(\n _slice: MediaPageOptions | null,\n page: PageModuleApi,\n): MediaPageApi {\n const actions = useMediaActions();\n return useMemo(\n () => ({\n ...actions,\n set: (media: MediaPageConfig) => page.set({ media }),\n }),\n [actions, page],\n );\n}\n\nexport const mediaModule = defineModule({\n id: \"media\",\n context: MediaContext,\n Provider: MediaProvider,\n Overlay: MediaOverlay,\n registry: {\n cleanupDelayMs: 600,\n keyPolicy: \"singleton\",\n lifecycle: \"immediate\",\n singletonKey: MEDIA_REGISTRY_KEY,\n },\n page: {\n select: (config) => selectPageMedia(config.media),\n entries: (slice: MediaPageOptions) => [\n { key: MEDIA_REGISTRY_KEY, value: slice },\n ],\n use: useMediaPage,\n },\n});\n\ndeclare module \"@omerdlw/base-framework/kernel\" {\n interface CoreModules {\n media: typeof mediaModule;\n }\n interface PageConfig {\n media?: MediaPageConfig;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../src/modules/media/module.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../src/modules/media/module.tsx"],"names":[],"mappings":"AASA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,SAAS,CAAC;AAgBjB,eAAO,MAAM,WAAW,mIAkBtB,CAAC;AAEH,OAAO,QAAQ,gCAAgC,CAAC;IAC9C,UAAU,WAAW;QACnB,KAAK,EAAE,OAAO,WAAW,CAAC;KAC3B;IACD,UAAU,UAAU;QAClB,KAAK,CAAC,EAAE,eAAe,CAAC;KACzB;CACF"}
|
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
import { type MediaSourceProps } from "./types";
|
|
2
|
-
/** Declarative form of `useMedia`: mount it anywhere to register an audio source. */
|
|
3
2
|
export declare function MediaSource(props: MediaSourceProps): null;
|
|
4
|
-
/**
|
|
5
|
-
* Plays whatever the current page declared with `usePage({ media })`. The
|
|
6
|
-
* registry drops the value when the page goes away, which stops the audio.
|
|
7
|
-
*/
|
|
8
3
|
export declare function MediaOverlay(): null;
|
|
9
4
|
//# sourceMappingURL=overlay.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../../src/modules/media/overlay.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAyB,KAAK,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEvE,
|
|
1
|
+
{"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../../src/modules/media/overlay.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAyB,KAAK,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEvE,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,QAGlD;AAED,wBAAgB,YAAY,SAO3B"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function toggleElement(element: HTMLMediaElement | null): void;
|
|
2
|
+
export declare function safePlay(element: HTMLMediaElement): void;
|
|
3
|
+
export declare function sameElements(a: readonly (HTMLMediaElement | null)[], b: readonly (HTMLMediaElement | null)[]): boolean;
|
|
4
|
+
export declare function bindFollowers(transport: HTMLMediaElement, followers: readonly HTMLMediaElement[]): () => void;
|
|
5
|
+
//# sourceMappingURL=playback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playback.d.ts","sourceRoot":"","sources":["../../../src/modules/media/playback.ts"],"names":[],"mappings":"AAIA,wBAAgB,aAAa,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,GAAG,IAAI,CAOpE;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAIxD;AAED,wBAAgB,YAAY,CAC1B,CAAC,EAAE,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,EAAE,EACvC,CAAC,EAAE,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,EAAE,GACtC,OAAO,CAIT;AAED,wBAAgB,aAAa,CAC3B,SAAS,EAAE,gBAAgB,EAC3B,SAAS,EAAE,SAAS,gBAAgB,EAAE,GACrC,MAAM,IAAI,CAgDZ"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type MediaEntry, type MediaEntryInput, type MediaPageConfig, type MediaPageOptions, type MediaSession, type MediaState } from "./types";
|
|
2
|
+
export declare function resolveMediaSession(sources: readonly MediaEntry[]): MediaSession | null;
|
|
3
|
+
export declare function createMediaState(session: MediaSession | null): MediaState;
|
|
4
|
+
export declare function mediaStatesEqual(a: MediaState, b: MediaState): boolean;
|
|
5
|
+
export declare function mergeMediaSource(current: MediaEntry | undefined, input: MediaEntryInput, order: number): MediaEntry;
|
|
6
|
+
export declare function selectPageMedia(media: MediaPageConfig | null | undefined): MediaPageOptions | null;
|
|
7
|
+
export declare function findDisplacedAudio(entries: readonly MediaEntry[], session: MediaSession | null, newId: string): MediaEntry[];
|
|
8
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/modules/media/session.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,UAAU,EAChB,MAAM,SAAS,CAAC;AAMjB,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,SAAS,UAAU,EAAE,GAC7B,YAAY,GAAG,IAAI,CAyBrB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,GAAG,UAAU,CAYzE;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAEtE;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,UAAU,GAAG,SAAS,EAC/B,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,MAAM,GACZ,UAAU,CAYZ;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,GACxC,gBAAgB,GAAG,IAAI,CAIzB;AACD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,OAAO,EAAE,YAAY,GAAG,IAAI,EAC5B,KAAK,EAAE,MAAM,GACZ,UAAU,EAAE,CAWd"}
|
|
@@ -66,7 +66,6 @@ export interface MediaHandle {
|
|
|
66
66
|
}
|
|
67
67
|
export interface MediaSourceProps extends MediaOptions {
|
|
68
68
|
}
|
|
69
|
-
/** `usePage({ media })`: a file URL, or the options of one audio source. */
|
|
70
69
|
export type MediaPageOptions = Omit<MediaOptions, "enabled" | "id">;
|
|
71
70
|
export type MediaPageConfig = string | (MediaPageOptions & {
|
|
72
71
|
registry?: RegistryMetadata;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/modules/media/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAE1C,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,OAAO,CAAC,CAAC,GAAG;IACxE,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,SAAS,UAAU,EAAE,CAAC;IACjC,OAAO,EAAE,UAAU,CAAC;IACpB,SAAS,EAAE,UAAU,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,cAAc,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACxC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,YAAY,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;CACjD;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,gBAAiB,SAAQ,YAAY;CAAG;AAEzD,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/modules/media/types.ts"],"names":[],"mappings":"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"}
|