2021-06-18 13:05:06 +02:00
|
|
|
import type {$IntentionalAny} from '../../types'
|
|
|
|
import Stack from '../../utils/Stack'
|
|
|
|
import type {IDerivation} from '../IDerivation'
|
|
|
|
|
|
|
|
function createMechanism() {
|
|
|
|
const noop = () => {}
|
|
|
|
|
|
|
|
const stack = new Stack<Collector>()
|
|
|
|
const noopCollector: Collector = noop
|
|
|
|
|
|
|
|
type Collector = (d: IDerivation<$IntentionalAny>) => void
|
|
|
|
|
2021-07-07 11:50:23 +02:00
|
|
|
const pushCollector = (collector: Collector): void => {
|
2021-06-18 13:05:06 +02:00
|
|
|
stack.push(collector)
|
2021-07-07 11:50:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const popCollector = (collector: Collector): void => {
|
|
|
|
const existing = stack.peek()
|
|
|
|
if (existing !== collector) {
|
|
|
|
throw new Error(`Popped collector is not on top of the stack`)
|
|
|
|
}
|
2021-06-18 13:05:06 +02:00
|
|
|
stack.pop()
|
|
|
|
}
|
|
|
|
|
|
|
|
const startIgnoringDependencies = () => {
|
|
|
|
stack.push(noopCollector)
|
|
|
|
}
|
|
|
|
|
|
|
|
const stopIgnoringDependencies = () => {
|
|
|
|
if (stack.peek() !== noopCollector) {
|
|
|
|
if (process.env.NODE_ENV === 'development') {
|
|
|
|
console.warn('This should never happen')
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
stack.pop()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const reportResolutionStart = (d: IDerivation<$IntentionalAny>) => {
|
|
|
|
const possibleCollector = stack.peek()
|
|
|
|
if (possibleCollector) {
|
|
|
|
possibleCollector(d)
|
|
|
|
}
|
|
|
|
|
|
|
|
stack.push(noopCollector)
|
|
|
|
}
|
|
|
|
|
|
|
|
const reportResolutionEnd = (_d: IDerivation<$IntentionalAny>) => {
|
|
|
|
stack.pop()
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
type: 'Dataverse_discoveryMechanism' as 'Dataverse_discoveryMechanism',
|
|
|
|
startIgnoringDependencies,
|
|
|
|
stopIgnoringDependencies,
|
|
|
|
reportResolutionStart,
|
|
|
|
reportResolutionEnd,
|
2021-07-07 11:50:23 +02:00
|
|
|
pushCollector,
|
|
|
|
popCollector,
|
2021-06-18 13:05:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function getSharedMechanism(): ReturnType<typeof createMechanism> {
|
|
|
|
const varName = '__dataverse_discoveryMechanism_sharedStack'
|
|
|
|
if (global) {
|
|
|
|
const existingMechanism: ReturnType<typeof createMechanism> | undefined =
|
|
|
|
// @ts-ignore ignore
|
|
|
|
global[varName]
|
|
|
|
if (
|
|
|
|
existingMechanism &&
|
|
|
|
typeof existingMechanism === 'object' &&
|
|
|
|
existingMechanism.type === 'Dataverse_discoveryMechanism'
|
|
|
|
) {
|
|
|
|
return existingMechanism
|
|
|
|
} else {
|
|
|
|
const mechanism = createMechanism()
|
|
|
|
// @ts-ignore ignore
|
|
|
|
global[varName] = mechanism
|
|
|
|
return mechanism
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return createMechanism()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export const {
|
|
|
|
startIgnoringDependencies,
|
|
|
|
stopIgnoringDependencies,
|
|
|
|
reportResolutionEnd,
|
|
|
|
reportResolutionStart,
|
2021-07-07 11:50:23 +02:00
|
|
|
pushCollector,
|
|
|
|
popCollector,
|
2021-06-18 13:05:06 +02:00
|
|
|
} = getSharedMechanism()
|