mobx-keystone-mindreframer
Version:
A MobX powered state management solution based on data trees with first class support for Typescript, snapshots, patches and much more
124 lines (109 loc) • 2.86 kB
text/typescript
import { v4 as uuidv4 } from "uuid"
import { failure, inDevMode } from "../utils"
import { toBase64 } from "../utils/toBase64"
/**
* Model auto type-checking mode.
*/
export enum ModelAutoTypeCheckingMode {
/**
* Auto type check models only in dev mode
*/
DevModeOnly = "devModeOnly",
/**
* Auto type check models no matter the current environment
*/
AlwaysOn = "alwaysOn",
/**
* Do not auto type check models no matter the current environment
*/
AlwaysOff = "alwaysOff",
}
/**
* Global config object.
*/
export interface GlobalConfig {
/**
* Model auto type-checking mode.
*/
modelAutoTypeChecking: ModelAutoTypeCheckingMode
/**
* ID generator function for model ids.
*/
modelIdGenerator(): string
/**
* Allow array elements to be `undefined`.
*/
allowUndefinedArrayElements: boolean
/**
* Enables/disables warnings related to duplicated model names (defaults to `true`).
* Usually set to false in test environments (e.g. jest).
*/
showDuplicateModelNameWarnings: boolean
}
let localId = 0
const localBaseId = shortenUuid(uuidv4())
function defaultModelIdGenerator(): string {
// we use base 36 for local id since it is short and fast
const id = localId.toString(36) + "-" + localBaseId
localId++
return id
}
// defaults
let globalConfig: GlobalConfig = {
modelAutoTypeChecking: ModelAutoTypeCheckingMode.DevModeOnly,
modelIdGenerator: defaultModelIdGenerator,
allowUndefinedArrayElements: false,
showDuplicateModelNameWarnings: true,
}
/**
* Partially sets the current global config.
*
* @param config Partial object with the new configurations. Options not included in the object won't be changed.
*/
export function setGlobalConfig(config: Partial<GlobalConfig>) {
globalConfig = Object.freeze({
...globalConfig,
...config,
})
}
/**
* Returns the current global config object.
*
* @returns
*/
export function getGlobalConfig(): Readonly<GlobalConfig> {
return globalConfig
}
/**
* @ignore
* @internal
*
* Returns if the auto type checking for models is enabled.
*
* @returns
*/
export function isModelAutoTypeCheckingEnabled() {
switch (getGlobalConfig().modelAutoTypeChecking) {
case ModelAutoTypeCheckingMode.DevModeOnly:
return inDevMode()
case ModelAutoTypeCheckingMode.AlwaysOff:
return false
case ModelAutoTypeCheckingMode.AlwaysOn:
return true
default:
throw failure(
`invalid 'modelAutoTypeChecking' config value - ${globalConfig.modelAutoTypeChecking}`
)
}
}
function shortenUuid(uuid: string): string {
// remove non-hex chars
const hex = uuid.split("-").join("")
// convert to base64
const hexMatch = hex.match(/\w{2}/g)!
const str = String.fromCharCode.apply(
null,
hexMatch.map((a) => parseInt(a, 16))
)
return toBase64(str)
}