All checks were successful
Publish To Prod / deploy_and_publish (push) Successful in 35s
86 lines
1.7 KiB
TypeScript
86 lines
1.7 KiB
TypeScript
import {
|
|
Patch,
|
|
PatchListener,
|
|
Drafted,
|
|
Immer,
|
|
DRAFT_STATE,
|
|
ImmerState,
|
|
ProxyType,
|
|
getPlugin
|
|
} from "../internal"
|
|
import {die} from "../utils/errors"
|
|
|
|
/** Each scope represents a `produce` call. */
|
|
|
|
export interface ImmerScope {
|
|
patches_?: Patch[]
|
|
inversePatches_?: Patch[]
|
|
canAutoFreeze_: boolean
|
|
drafts_: any[]
|
|
parent_?: ImmerScope
|
|
patchListener_?: PatchListener
|
|
immer_: Immer
|
|
unfinalizedDrafts_: number
|
|
}
|
|
|
|
let currentScope: ImmerScope | undefined
|
|
|
|
export function getCurrentScope() {
|
|
if (__DEV__ && !currentScope) die(0)
|
|
return currentScope!
|
|
}
|
|
|
|
function createScope(
|
|
parent_: ImmerScope | undefined,
|
|
immer_: Immer
|
|
): ImmerScope {
|
|
return {
|
|
drafts_: [],
|
|
parent_,
|
|
immer_,
|
|
// Whenever the modified draft contains a draft from another scope, we
|
|
// need to prevent auto-freezing so the unowned draft can be finalized.
|
|
canAutoFreeze_: true,
|
|
unfinalizedDrafts_: 0
|
|
}
|
|
}
|
|
|
|
export function usePatchesInScope(
|
|
scope: ImmerScope,
|
|
patchListener?: PatchListener
|
|
) {
|
|
if (patchListener) {
|
|
getPlugin("Patches") // assert we have the plugin
|
|
scope.patches_ = []
|
|
scope.inversePatches_ = []
|
|
scope.patchListener_ = patchListener
|
|
}
|
|
}
|
|
|
|
export function revokeScope(scope: ImmerScope) {
|
|
leaveScope(scope)
|
|
scope.drafts_.forEach(revokeDraft)
|
|
// @ts-ignore
|
|
scope.drafts_ = null
|
|
}
|
|
|
|
export function leaveScope(scope: ImmerScope) {
|
|
if (scope === currentScope) {
|
|
currentScope = scope.parent_
|
|
}
|
|
}
|
|
|
|
export function enterScope(immer: Immer) {
|
|
return (currentScope = createScope(currentScope, immer))
|
|
}
|
|
|
|
function revokeDraft(draft: Drafted) {
|
|
const state: ImmerState = draft[DRAFT_STATE]
|
|
if (
|
|
state.type_ === ProxyType.ProxyObject ||
|
|
state.type_ === ProxyType.ProxyArray
|
|
)
|
|
state.revoke_()
|
|
else state.revoked_ = true
|
|
}
|