mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 02:44:02 +00:00
refactor: enforce import directions and expose source factories
This commit is contained in:
1 parent
704e0fcc51
commit
cc960b0dbe
41 files changed
+1080
-417
No files matched your search
@@ -0,0 +1,52 @@
|
||||
/** Bind a source contract once for the application without replacing its layer instance. */
|
||||
export function createSourceSlot(
|
||||
initial,
|
||||
methods,
|
||||
label = 'Source',
|
||||
optional = {},
|
||||
) {
|
||||
let active = initial;
|
||||
let binding = null;
|
||||
const source = Object.fromEntries(
|
||||
[...methods, ...Object.keys(optional)].map((method) => [
|
||||
method,
|
||||
(...args) => {
|
||||
if (typeof active?.[method] !== 'function' && optional[method])
|
||||
return optional[method](...args);
|
||||
if (typeof active?.[method] !== 'function')
|
||||
throw new Error(`${label} is not configured`);
|
||||
const owner = binding;
|
||||
const provider = active;
|
||||
const value = provider[method](...args);
|
||||
if (value && typeof value.then === 'function')
|
||||
return value.then((result) => {
|
||||
if (binding !== owner || active !== provider)
|
||||
throw new DOMException(`${label} was replaced`, 'AbortError');
|
||||
return result;
|
||||
});
|
||||
return value;
|
||||
},
|
||||
]),
|
||||
);
|
||||
for (const property of ['label', 'attribution']) {
|
||||
Object.defineProperty(source, property, {
|
||||
enumerable: true,
|
||||
get: () => active?.[property],
|
||||
});
|
||||
}
|
||||
return {
|
||||
source,
|
||||
configure(next) {
|
||||
if (methods.some((method) => typeof next?.[method] !== 'function'))
|
||||
throw new TypeError(`Invalid ${label.toLowerCase()}`);
|
||||
const owner = Symbol(label);
|
||||
active = next;
|
||||
binding = owner;
|
||||
return () => {
|
||||
if (binding !== owner) return;
|
||||
active = null;
|
||||
binding = null;
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user