fix engram rtk
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good

This commit is contained in:
juanjo
2026-04-16 18:24:13 +02:00
parent a8dbb62b09
commit 0fc5392bd2
1030 changed files with 947923 additions and 3 deletions

21
frontend/node_modules/immer/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Michel Weststrate
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

8
frontend/node_modules/immer/dist/cjs/index.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
'use strict'
if (process.env.NODE_ENV === 'production') {
module.exports = require('./immer.cjs.production.js')
} else {
module.exports = require('./immer.cjs.development.js')
}

112
frontend/node_modules/immer/dist/cjs/index.js.flow generated vendored Normal file
View File

@@ -0,0 +1,112 @@
// @flow
export interface Patch {
op: "replace" | "remove" | "add";
path: (string | number)[];
value?: any;
}
export type PatchListener = (patches: Patch[], inversePatches: Patch[]) => void
type Base = {...} | Array<any>
interface IProduce {
/**
* Immer takes a state, and runs a function against it.
* That function can freely mutate the state, as it will create copies-on-write.
* This means that the original state will stay unchanged, and once the function finishes, the modified state is returned.
*
* If the first argument is a function, this is interpreted as the recipe, and will create a curried function that will execute the recipe
* any time it is called with the current state.
*
* @param currentState - the state to start with
* @param recipe - function that receives a proxy of the current state as first argument and which can be freely modified
* @param initialState - if a curried function is created and this argument was given, it will be used as fallback if the curried function is called with a state of undefined
* @returns The next state: a new state, or the current state if nothing was modified
*/
<S: Base>(
currentState: S,
recipe: (draftState: S) => S | void,
patchListener?: PatchListener
): S;
// curried invocations with initial state
<S: Base, A = void, B = void, C = void>(
recipe: (draftState: S, a: A, b: B, c: C, ...extraArgs: any[]) => S | void,
initialState: S
): (currentState: S | void, a: A, b: B, c: C, ...extraArgs: any[]) => S;
// curried invocations without initial state
<S: Base, A = void, B = void, C = void>(
recipe: (draftState: S, a: A, b: B, c: C, ...extraArgs: any[]) => S | void
): (currentState: S, a: A, b: B, c: C, ...extraArgs: any[]) => S;
}
interface IProduceWithPatches {
/**
* Like `produce`, but instead of just returning the new state,
* a tuple is returned with [nextState, patches, inversePatches]
*
* Like produce, this function supports currying
*/
<S: Base>(
currentState: S,
recipe: (draftState: S) => S | void
): [S, Patch[], Patch[]];
// curried invocations with initial state
<S: Base, A = void, B = void, C = void>(
recipe: (draftState: S, a: A, b: B, c: C, ...extraArgs: any[]) => S | void,
initialState: S
): (currentState: S | void, a: A, b: B, c: C, ...extraArgs: any[]) => [S, Patch[], Patch[]];
// curried invocations without initial state
<S: Base, A = void, B = void, C = void>(
recipe: (draftState: S, a: A, b: B, c: C, ...extraArgs: any[]) => S | void
): (currentState: S, a: A, b: B, c: C, ...extraArgs: any[]) => [S, Patch[], Patch[]];
}
declare export var produce: IProduce
declare export var produceWithPatches: IProduceWithPatches
declare export var nothing: typeof undefined
declare export var immerable: Symbol
/**
* Automatically freezes any state trees generated by immer.
* This protects against accidental modifications of the state tree outside of an immer function.
* This comes with a performance impact, so it is recommended to disable this option in production.
* By default it is turned on during local development, and turned off in production.
*/
declare export function setAutoFreeze(autoFreeze: boolean): void
/**
* Pass false to disable strict shallow copy.
*
* By default, immer does not copy the object descriptors such as getter, setter and non-enumrable properties.
*/
declare export function setUseStrictShallowCopy(useStrictShallowCopy: boolean): void
declare export function applyPatches<S>(state: S, patches: Patch[]): S
declare export function original<S>(value: S): S
declare export function current<S>(value: S): S
declare export function isDraft(value: any): boolean
/**
* Creates a mutable draft from an (immutable) object / array.
* The draft can be modified until `finishDraft` is called
*/
declare export function createDraft<T>(base: T): T
/**
* Given a draft that was created using `createDraft`,
* finalizes the draft into a new immutable object.
* Optionally a patch-listener can be provided to gather the patches that are needed to construct the object.
*/
declare export function finishDraft<T>(base: T, listener?: PatchListener): T
declare export function enableMapSet(): void
declare export function enablePatches(): void
declare export function enableArrayMethods(): void
declare export function freeze<T>(obj: T, freeze?: boolean): T

317
frontend/node_modules/immer/dist/immer.d.ts generated vendored Normal file
View File

@@ -0,0 +1,317 @@
/**
* The sentinel value returned by producers to replace the draft with undefined.
*/
declare const NOTHING: unique symbol;
/**
* To let Immer treat your class instances as plain immutable objects
* (albeit with a custom prototype), you must define either an instance property
* or a static property on each of your custom classes.
*
* Otherwise, your class instance will never be drafted, which means it won't be
* safe to mutate in a produce callback.
*/
declare const DRAFTABLE: unique symbol;
type AnyFunc = (...args: any[]) => any;
type PrimitiveType = number | string | boolean;
/** Object types that should never be mapped */
type AtomicObject = Function | Promise<any> | Date | RegExp;
/**
* If the lib "ES2015.Collection" is not included in tsconfig.json,
* types like ReadonlyArray, WeakMap etc. fall back to `any` (specified nowhere)
* or `{}` (from the node types), in both cases entering an infinite recursion in
* pattern matching type mappings
* This type can be used to cast these types to `void` in these cases.
*/
type IfAvailable<T, Fallback = void> = true | false extends (T extends never ? true : false) ? Fallback : keyof T extends never ? Fallback : T;
/**
* These should also never be mapped but must be tested after regular Map and
* Set
*/
type WeakReferences = IfAvailable<WeakMap<any, any>> | IfAvailable<WeakSet<any>>;
type WritableDraft<T> = T extends any[] ? number extends T["length"] ? Draft<T[number]>[] : WritableNonArrayDraft<T> : WritableNonArrayDraft<T>;
type WritableNonArrayDraft<T> = {
-readonly [K in keyof T]: T[K] extends infer V ? V extends object ? Draft<V> : V : never;
};
/** Convert a readonly type into a mutable type, if possible */
type Draft<T> = T extends PrimitiveType ? T : T extends AtomicObject ? T : T extends ReadonlyMap<infer K, infer V> ? Map<Draft<K>, Draft<V>> : T extends ReadonlySet<infer V> ? Set<Draft<V>> : T extends WeakReferences ? T : T extends object ? WritableDraft<T> : T;
/** Convert a mutable type into a readonly type */
type Immutable<T> = T extends PrimitiveType ? T : T extends AtomicObject ? T : T extends ReadonlyMap<infer K, infer V> ? ReadonlyMap<Immutable<K>, Immutable<V>> : T extends ReadonlySet<infer V> ? ReadonlySet<Immutable<V>> : T extends WeakReferences ? T : T extends object ? {
readonly [K in keyof T]: Immutable<T[K]>;
} : T;
interface Patch {
op: "replace" | "remove" | "add";
path: (string | number)[];
value?: any;
}
type PatchListener = (patches: Patch[], inversePatches: Patch[]) => void;
/**
* Utility types
*/
type PatchesTuple<T> = readonly [T, Patch[], Patch[]];
type ValidRecipeReturnType<State> = State | void | undefined | (State extends undefined ? typeof NOTHING : never);
type ReturnTypeWithPatchesIfNeeded<State, UsePatches extends boolean> = UsePatches extends true ? PatchesTuple<State> : State;
/**
* Core Producer inference
*/
type InferRecipeFromCurried<Curried> = Curried extends (base: infer State, ...rest: infer Args) => any ? ReturnType<Curried> extends State ? (draft: Draft<State>, ...rest: Args) => ValidRecipeReturnType<Draft<State>> : never : never;
type InferInitialStateFromCurried<Curried> = Curried extends (base: infer State, ...rest: any[]) => any ? State : never;
type InferCurriedFromRecipe<Recipe, UsePatches extends boolean> = Recipe extends (draft: infer DraftState, ...args: infer RestArgs) => any ? ReturnType<Recipe> extends ValidRecipeReturnType<DraftState> ? (base: Immutable<DraftState>, ...args: RestArgs) => ReturnTypeWithPatchesIfNeeded<DraftState, UsePatches> : never : never;
type InferCurriedFromInitialStateAndRecipe<State, Recipe, UsePatches extends boolean> = Recipe extends (draft: Draft<State>, ...rest: infer RestArgs) => ValidRecipeReturnType<State> ? (base?: State | undefined, ...args: RestArgs) => ReturnTypeWithPatchesIfNeeded<State, UsePatches> : never;
/**
* The `produce` function takes a value and a "recipe function" (whose
* return value often depends on the base state). The recipe function is
* free to mutate its first argument however it wants. All mutations are
* only ever applied to a __copy__ of the base state.
*
* Pass only a function to create a "curried producer" which relieves you
* from passing the recipe function every time.
*
* Only plain objects and arrays are made mutable. All other objects are
* considered uncopyable.
*
* Note: This function is __bound__ to its `Immer` instance.
*
* @param {any} base - the initial state
* @param {Function} producer - function that receives a proxy of the base state as first argument and which can be freely modified
* @param {Function} patchListener - optional function that will be called with all the patches produced here
* @returns {any} a new state, or the initial state if nothing was modified
*/
interface IProduce {
/** Curried producer that infers the recipe from the curried output function (e.g. when passing to setState) */
<Curried>(recipe: InferRecipeFromCurried<Curried>, initialState?: InferInitialStateFromCurried<Curried>): Curried;
/** Curried producer that infers curried from the recipe */
<Recipe extends AnyFunc>(recipe: Recipe): InferCurriedFromRecipe<Recipe, false>;
/** Curried producer that infers curried from the State generic, which is explicitly passed in. */
<State>(recipe: (state: Draft<State>, initialState: State) => ValidRecipeReturnType<State>): (state?: State) => State;
<State, Args extends any[]>(recipe: (state: Draft<State>, ...args: Args) => ValidRecipeReturnType<State>, initialState: State): (state?: State, ...args: Args) => State;
<State>(recipe: (state: Draft<State>) => ValidRecipeReturnType<State>): (state: State) => State;
<State, Args extends any[]>(recipe: (state: Draft<State>, ...args: Args) => ValidRecipeReturnType<State>): (state: State, ...args: Args) => State;
/** Curried producer with initial state, infers recipe from initial state */
<State, Recipe extends Function>(recipe: Recipe, initialState: State): InferCurriedFromInitialStateAndRecipe<State, Recipe, false>;
/** Normal producer */
<Base, D = Draft<Base>>(// By using a default inferred D, rather than Draft<Base> in the recipe, we can override it.
base: Base, recipe: (draft: D) => ValidRecipeReturnType<D>, listener?: PatchListener): Base;
}
/**
* Like `produce`, but instead of just returning the new state,
* a tuple is returned with [nextState, patches, inversePatches]
*
* Like produce, this function supports currying
*/
interface IProduceWithPatches {
<Recipe extends AnyFunc>(recipe: Recipe): InferCurriedFromRecipe<Recipe, true>;
<State, Recipe extends Function>(recipe: Recipe, initialState: State): InferCurriedFromInitialStateAndRecipe<State, Recipe, true>;
<Base, D = Draft<Base>>(base: Base, recipe: (draft: D) => ValidRecipeReturnType<D>, listener?: PatchListener): PatchesTuple<Base>;
}
/**
* The type for `recipe function`
*/
type Producer<T> = (draft: Draft<T>) => ValidRecipeReturnType<Draft<T>>;
type Objectish = AnyObject | AnyArray | AnyMap | AnySet;
type AnyObject = {
[key: string]: any;
};
type AnyArray = Array<any>;
type AnySet = Set<any>;
type AnyMap = Map<any, any>;
/** Returns true if the given value is an Immer draft */
declare let isDraft: (value: any) => boolean;
/** Returns true if the given value can be drafted by Immer */
declare function isDraftable(value: any): boolean;
/** Get the underlying object that is represented by the given draft */
declare function original<T>(value: T): T | undefined;
/**
* Freezes draftable objects. Returns the original object.
* By default freezes shallowly, but if the second argument is `true` it will freeze recursively.
*
* @param obj
* @param deep
*/
declare function freeze<T>(obj: T, deep?: boolean): T;
interface ProducersFns {
produce: IProduce;
produceWithPatches: IProduceWithPatches;
}
type StrictMode = boolean | "class_only";
declare class Immer implements ProducersFns {
autoFreeze_: boolean;
useStrictShallowCopy_: StrictMode;
useStrictIteration_: boolean;
constructor(config?: {
autoFreeze?: boolean;
useStrictShallowCopy?: StrictMode;
useStrictIteration?: boolean;
});
/**
* The `produce` function takes a value and a "recipe function" (whose
* return value often depends on the base state). The recipe function is
* free to mutate its first argument however it wants. All mutations are
* only ever applied to a __copy__ of the base state.
*
* Pass only a function to create a "curried producer" which relieves you
* from passing the recipe function every time.
*
* Only plain objects and arrays are made mutable. All other objects are
* considered uncopyable.
*
* Note: This function is __bound__ to its `Immer` instance.
*
* @param {any} base - the initial state
* @param {Function} recipe - function that receives a proxy of the base state as first argument and which can be freely modified
* @param {Function} patchListener - optional function that will be called with all the patches produced here
* @returns {any} a new state, or the initial state if nothing was modified
*/
produce: IProduce;
produceWithPatches: IProduceWithPatches;
createDraft<T extends Objectish>(base: T): Draft<T>;
finishDraft<D extends Draft<any>>(draft: D, patchListener?: PatchListener): D extends Draft<infer T> ? T : never;
/**
* Pass true to automatically freeze all copies created by Immer.
*
* By default, auto-freezing is enabled.
*/
setAutoFreeze(value: boolean): void;
/**
* Pass true to enable strict shallow copy.
*
* By default, immer does not copy the object descriptors such as getter, setter and non-enumrable properties.
*/
setUseStrictShallowCopy(value: StrictMode): void;
/**
* Pass false to use faster iteration that skips non-enumerable properties
* but still handles symbols for compatibility.
*
* By default, strict iteration is enabled (includes all own properties).
*/
setUseStrictIteration(value: boolean): void;
shouldUseStrictIteration(): boolean;
applyPatches<T extends Objectish>(base: T, patches: readonly Patch[]): T;
}
/** Takes a snapshot of the current state of a draft and finalizes it (but without freezing). This is a great utility to print the current state during debugging (no Proxies in the way). The output of current can also be safely leaked outside the producer. */
declare function current<T>(value: T): T;
declare function enablePatches(): void;
declare function enableMapSet(): void;
/**
* Enables optimized array method handling for Immer drafts.
*
* This plugin overrides array methods to avoid unnecessary Proxy creation during iteration,
* significantly improving performance for array-heavy operations.
*
* **Mutating methods** (push, pop, shift, unshift, splice, sort, reverse):
* Operate directly on the copy without creating per-element proxies.
*
* **Non-mutating methods** fall into categories:
* - **Subset operations** (filter, slice, find, findLast): Return draft proxies - mutations track
* - **Transform operations** (concat, flat): Return base values - mutations don't track
* - **Primitive-returning** (indexOf, includes, some, every, etc.): Return primitives
*
* **Important**: Callbacks for overridden methods receive base values, not drafts.
* This is the core performance optimization.
*
* @example
* ```ts
* import { enableArrayMethods, produce } from "immer"
*
* enableArrayMethods()
*
* const next = produce(state, draft => {
* // Optimized - no proxy creation per element
* draft.items.sort((a, b) => a.value - b.value)
*
* // filter returns drafts - mutations propagate
* const filtered = draft.items.filter(x => x.value > 5)
* filtered[0].value = 999 // Affects draft.items[originalIndex]
* })
* ```
*
* @see https://immerjs.github.io/immer/array-methods
*/
declare function enableArrayMethods(): void;
/**
* The `produce` function takes a value and a "recipe function" (whose
* return value often depends on the base state). The recipe function is
* free to mutate its first argument however it wants. All mutations are
* only ever applied to a __copy__ of the base state.
*
* Pass only a function to create a "curried producer" which relieves you
* from passing the recipe function every time.
*
* Only plain objects and arrays are made mutable. All other objects are
* considered uncopyable.
*
* Note: This function is __bound__ to its `Immer` instance.
*
* @param {any} base - the initial state
* @param {Function} producer - function that receives a proxy of the base state as first argument and which can be freely modified
* @param {Function} patchListener - optional function that will be called with all the patches produced here
* @returns {any} a new state, or the initial state if nothing was modified
*/
declare const produce: IProduce;
/**
* Like `produce`, but `produceWithPatches` always returns a tuple
* [nextState, patches, inversePatches] (instead of just the next state)
*/
declare const produceWithPatches: IProduceWithPatches;
/**
* Pass true to automatically freeze all copies created by Immer.
*
* Always freeze by default, even in production mode
*/
declare const setAutoFreeze: (value: boolean) => void;
/**
* Pass true to enable strict shallow copy.
*
* By default, immer does not copy the object descriptors such as getter, setter and non-enumrable properties.
*/
declare const setUseStrictShallowCopy: (value: StrictMode) => void;
/**
* Pass false to use loose iteration that only processes enumerable string properties.
* This skips symbols and non-enumerable properties for maximum performance.
*
* By default, strict iteration is enabled (includes all own properties).
*/
declare const setUseStrictIteration: (value: boolean) => void;
/**
* Apply an array of Immer patches to the first argument.
*
* This function is a producer, which means copy-on-write is in effect.
*/
declare const applyPatches: <T extends Objectish>(base: T, patches: readonly Patch[]) => T;
/**
* Create an Immer draft from the given base state, which may be a draft itself.
* The draft can be modified until you finalize it with the `finishDraft` function.
*/
declare const createDraft: <T extends Objectish>(base: T) => Draft<T>;
/**
* Finalize an Immer draft from a `createDraft` call, returning the base state
* (if no changes were made) or a modified copy. The draft must *not* be
* mutated afterwards.
*
* Pass a function as the 2nd argument to generate Immer patches based on the
* changes that were made.
*/
declare const finishDraft: <D extends unknown>(draft: D, patchListener?: PatchListener | undefined) => D extends Draft<infer T> ? T : never;
/**
* This function is actually a no-op, but can be used to cast an immutable type
* to an draft type and make TypeScript happy
*
* @param value
*/
declare let castDraft: <T>(value: T) => Draft<T>;
/**
* This function is actually a no-op, but can be used to cast a mutable type
* to an immutable type and make TypeScript happy
* @param value
*/
declare let castImmutable: <T>(value: T) => Immutable<T>;
export { Draft, Immer, Immutable, Objectish, Patch, PatchListener, Producer, StrictMode, WritableDraft, applyPatches, castDraft, castImmutable, createDraft, current, enableArrayMethods, enableMapSet, enablePatches, finishDraft, freeze, DRAFTABLE as immerable, isDraft, isDraftable, NOTHING as nothing, original, produce, produceWithPatches, setAutoFreeze, setUseStrictIteration, setUseStrictShallowCopy };

1693
frontend/node_modules/immer/dist/immer.legacy-esm.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

1664
frontend/node_modules/immer/dist/immer.mjs generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
frontend/node_modules/immer/dist/immer.mjs.map generated vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

97
frontend/node_modules/immer/package.json generated vendored Normal file
View File

@@ -0,0 +1,97 @@
{
"name": "immer",
"version": "11.1.4",
"description": "Create your next immutable state by mutating the current one",
"main": "./dist/cjs/index.js",
"module": "./dist/immer.legacy-esm.js",
"exports": {
"./package.json": "./package.json",
".": {
"react-native": {
"types": "./dist/immer.d.ts",
"default": "./dist/immer.legacy-esm.js"
},
"import": {
"types": "./dist/immer.d.ts",
"default": "./dist/immer.mjs"
},
"require": {
"types": "./dist/immer.d.ts",
"default": "./dist/cjs/index.js"
}
}
},
"jsnext:main": "dist/immer.mjs",
"source": "src/immer.ts",
"types": "./dist/immer.d.ts",
"sideEffects": false,
"scripts": {
"test": "vitest run && yarn test:build && yarn test:flow",
"test:perf": "cd __performance_tests__ && node add-data.mjs && node todo.mjs && node incremental.mjs && node large-obj.mjs",
"test:flow": "yarn flow check __tests__/flow",
"test:build": "yarn build && vitest run --config vitest.config.build.ts",
"test:src": "vitest run",
"watch": "vitest",
"coverage": "vitest run --coverage",
"coveralls": "vitest run --coverage && cat ./coverage/lcov.info | ./node_modules/.bin/coveralls && rm -rf ./coverage",
"build": "tsup",
"publish-docs": "cd website && GIT_USER=mweststrate USE_SSH=true yarn docusaurus deploy",
"start": "cd website && yarn start",
"test:size": "yarn build && yarn import-size --report . produce enableMapSet enablePatches enableArrayMethods",
"test:sizequick": "yarn build && yarn import-size . produce"
},
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged"
}
},
"repository": {
"type": "git",
"url": "https://github.com/immerjs/immer.git"
},
"keywords": [
"immutable",
"mutable",
"copy-on-write"
],
"author": "Michel Weststrate <info@michel.codes>",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/immer"
},
"bugs": {
"url": "https://github.com/immerjs/immer/issues"
},
"homepage": "https://github.com/immerjs/immer#readme",
"files": [
"dist",
"compat",
"src"
],
"devDependencies": {
"@babel/core": "^7.21.3",
"@types/node": "^24.3.1",
"@vitest/coverage-v8": "2.1.9",
"coveralls": "^3.0.0",
"cpx2": "^3.0.0",
"deep-freeze": "^0.0.1",
"flow-bin": "^0.123.0",
"husky": "^1.2.0",
"immutable": "^3.8.2",
"import-size": "^1.0.2",
"lodash": "^4.17.4",
"lodash.clonedeep": "^4.5.0",
"prettier": "1.19.1",
"pretty-quick": "^1.8.0",
"redux": "^4.0.5",
"rimraf": "^2.6.2",
"seamless-immutable": "^7.1.3",
"semantic-release": "^17.0.2",
"tsup": "^6.7.0",
"type-plus": "^7.6.2",
"typescript": "^5.0.2",
"vite": "^5.4.0",
"vitest": "^2.0.0"
}
}

33
frontend/node_modules/immer/readme.md generated vendored Normal file
View File

@@ -0,0 +1,33 @@
<img src="images/immer-logo.svg" height="200px" align="right"/>
# Immer
[![npm](https://img.shields.io/npm/v/immer.svg)](https://www.npmjs.com/package/immer) [![Build Status](https://github.com/immerjs/immer/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/immerjs/immer/actions?query=branch%3Amain) [![Coverage Status](https://coveralls.io/repos/github/immerjs/immer/badge.svg?branch=main)](https://coveralls.io/github/immerjs/immer?branch=main) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier) [![OpenCollective](https://opencollective.com/immer/backers/badge.svg)](#backers) [![OpenCollective](https://opencollective.com/immer/sponsors/badge.svg)](#sponsors) [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/immerjs/immer)
_Create the next immutable state tree by simply modifying the current tree_
Winner of the "Breakthrough of the year" [React open source award](https://osawards.com/react/) and "Most impactful contribution" [JavaScript open source award](https://osawards.com/javascript/) in 2019
## Contribute using one-click online setup
You can use Gitpod (a free online VSCode like IDE) for contributing online. With a single click it will launch a workspace and automatically:
- clone the immer repo.
- install the dependencies.
- run `yarn run start`.
so that you can start coding straight away.
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/)
## Documentation
The documentation of this package is hosted at https://immerjs.github.io/immer/
## Support
Did Immer make a difference to your project? Join the open collective at https://opencollective.com/immer!
## Release notes
https://github.com/immerjs/immer/releases

46
frontend/node_modules/immer/src/core/current.ts generated vendored Normal file
View File

@@ -0,0 +1,46 @@
import {
die,
isDraft,
shallowCopy,
each,
DRAFT_STATE,
set,
ImmerState,
isDraftable,
isFrozen
} from "../internal"
/** Takes a snapshot of the current state of a draft and finalizes it (but without freezing). This is a great utility to print the current state during debugging (no Proxies in the way). The output of current can also be safely leaked outside the producer. */
export function current<T>(value: T): T
export function current(value: any): any {
if (!isDraft(value)) die(10, value)
return currentImpl(value)
}
function currentImpl(value: any): any {
if (!isDraftable(value) || isFrozen(value)) return value
const state: ImmerState | undefined = value[DRAFT_STATE]
let copy: any
let strict = true // Default to strict for compatibility
if (state) {
if (!state.modified_) return state.base_
// Optimization: avoid generating new drafts during copying
state.finalized_ = true
copy = shallowCopy(value, state.scope_.immer_.useStrictShallowCopy_)
strict = state.scope_.immer_.shouldUseStrictIteration()
} else {
copy = shallowCopy(value, true)
}
// recurse
each(
copy,
(key, childValue) => {
set(copy, key, currentImpl(childValue))
},
strict
)
if (state) {
state.finalized_ = false
}
return copy
}

318
frontend/node_modules/immer/src/core/finalize.ts generated vendored Normal file
View File

@@ -0,0 +1,318 @@
import {
ImmerScope,
DRAFT_STATE,
isDraftable,
NOTHING,
PatchPath,
each,
freeze,
ImmerState,
isDraft,
SetState,
set,
ArchType,
getPlugin,
die,
revokeScope,
isFrozen,
get,
Patch,
latest,
prepareCopy,
getFinalValue,
getValue,
ProxyArrayState
} from "../internal"
export function processResult(result: any, scope: ImmerScope) {
scope.unfinalizedDrafts_ = scope.drafts_.length
const baseDraft = scope.drafts_![0]
const isReplaced = result !== undefined && result !== baseDraft
if (isReplaced) {
if (baseDraft[DRAFT_STATE].modified_) {
revokeScope(scope)
die(4)
}
if (isDraftable(result)) {
// Finalize the result in case it contains (or is) a subset of the draft.
result = finalize(scope, result)
}
const {patchPlugin_} = scope
if (patchPlugin_) {
patchPlugin_.generateReplacementPatches_(
baseDraft[DRAFT_STATE].base_,
result,
scope
)
}
} else {
// Finalize the base draft.
result = finalize(scope, baseDraft)
}
maybeFreeze(scope, result, true)
revokeScope(scope)
if (scope.patches_) {
scope.patchListener_!(scope.patches_, scope.inversePatches_!)
}
return result !== NOTHING ? result : undefined
}
function finalize(rootScope: ImmerScope, value: any) {
// Don't recurse in tho recursive data structures
if (isFrozen(value)) return value
const state: ImmerState = value[DRAFT_STATE]
if (!state) {
const finalValue = handleValue(value, rootScope.handledSet_, rootScope)
return finalValue
}
// Never finalize drafts owned by another scope
if (!isSameScope(state, rootScope)) {
return value
}
// Unmodified draft, return the (frozen) original
if (!state.modified_) {
return state.base_
}
if (!state.finalized_) {
// Execute all registered draft finalization callbacks
const {callbacks_} = state
if (callbacks_) {
while (callbacks_.length > 0) {
const callback = callbacks_.pop()!
callback(rootScope)
}
}
generatePatchesAndFinalize(state, rootScope)
}
// By now the root copy has been fully updated throughout its tree
return state.copy_
}
function maybeFreeze(scope: ImmerScope, value: any, deep = false) {
// we never freeze for a non-root scope; as it would prevent pruning for drafts inside wrapping objects
if (!scope.parent_ && scope.immer_.autoFreeze_ && scope.canAutoFreeze_) {
freeze(value, deep)
}
}
function markStateFinalized(state: ImmerState) {
state.finalized_ = true
state.scope_.unfinalizedDrafts_--
}
let isSameScope = (state: ImmerState, rootScope: ImmerScope) =>
state.scope_ === rootScope
// A reusable empty array to avoid allocations
const EMPTY_LOCATIONS_RESULT: (string | symbol | number)[] = []
// Updates all references to a draft in its parent to the finalized value.
// This handles cases where the same draft appears multiple times in the parent, or has been moved around.
export function updateDraftInParent(
parent: ImmerState,
draftValue: any,
finalizedValue: any,
originalKey?: string | number | symbol
): void {
const parentCopy = latest(parent)
const parentType = parent.type_
// Fast path: Check if draft is still at original key
if (originalKey !== undefined) {
const currentValue = get(parentCopy, originalKey, parentType)
if (currentValue === draftValue) {
// Still at original location, just update it
set(parentCopy, originalKey, finalizedValue, parentType)
return
}
}
// Slow path: Build reverse mapping of all children
// to their indices in the parent, so that we can
// replace all locations where this draft appears.
// We only have to build this once per parent.
if (!parent.draftLocations_) {
const draftLocations = (parent.draftLocations_ = new Map())
// Use `each` which works on Arrays, Maps, and Objects
each(parentCopy, (key, value) => {
if (isDraft(value)) {
const keys = draftLocations.get(value) || []
keys.push(key)
draftLocations.set(value, keys)
}
})
}
// Look up all locations where this draft appears
const locations =
parent.draftLocations_.get(draftValue) ?? EMPTY_LOCATIONS_RESULT
// Update all locations
for (const location of locations) {
set(parentCopy, location, finalizedValue, parentType)
}
}
// Register a callback to finalize a child draft when the parent draft is finalized.
// This assumes there is a parent -> child relationship between the two drafts,
// and we have a key to locate the child in the parent.
export function registerChildFinalizationCallback(
parent: ImmerState,
child: ImmerState,
key: string | number | symbol
) {
parent.callbacks_.push(function childCleanup(rootScope) {
const state: ImmerState = child
// Can only continue if this is a draft owned by this scope
if (!state || !isSameScope(state, rootScope)) {
return
}
// Handle potential set value finalization first
rootScope.mapSetPlugin_?.fixSetContents(state)
const finalizedValue = getFinalValue(state)
// Update all locations in the parent that referenced this draft
updateDraftInParent(parent, state.draft_ ?? state, finalizedValue, key)
generatePatchesAndFinalize(state, rootScope)
})
}
function generatePatchesAndFinalize(state: ImmerState, rootScope: ImmerScope) {
const shouldFinalize =
state.modified_ &&
!state.finalized_ &&
(state.type_ === ArchType.Set ||
(state.type_ === ArchType.Array &&
(state as ProxyArrayState).allIndicesReassigned_) ||
(state.assigned_?.size ?? 0) > 0)
if (shouldFinalize) {
const {patchPlugin_} = rootScope
if (patchPlugin_) {
const basePath = patchPlugin_!.getPath(state)
if (basePath) {
patchPlugin_!.generatePatches_(state, basePath, rootScope)
}
}
markStateFinalized(state)
}
}
export function handleCrossReference(
target: ImmerState,
key: string | number | symbol,
value: any
) {
const {scope_} = target
// Check if value is a draft from this scope
if (isDraft(value)) {
const state: ImmerState = value[DRAFT_STATE]
if (isSameScope(state, scope_)) {
// Register callback to update this location when the draft finalizes
state.callbacks_.push(function crossReferenceCleanup() {
// Update the target location with finalized value
prepareCopy(target)
const finalizedValue = getFinalValue(state)
updateDraftInParent(target, value, finalizedValue, key)
})
}
} else if (isDraftable(value)) {
// Handle non-draft objects that might contain drafts
target.callbacks_.push(function nestedDraftCleanup() {
const targetCopy = latest(target)
// For Sets, check if value is still in the set
if (target.type_ === ArchType.Set) {
if (targetCopy.has(value)) {
// Process the value to replace any nested drafts
handleValue(value, scope_.handledSet_, scope_)
}
} else {
// Maps/objects
if (get(targetCopy, key, target.type_) === value) {
if (
scope_.drafts_.length > 1 &&
((target as Exclude<ImmerState, SetState>).assigned_!.get(key) ??
false) === true &&
target.copy_
) {
// This might be a non-draft value that has drafts
// inside. We do need to recurse here to handle those.
handleValue(
get(target.copy_, key, target.type_),
scope_.handledSet_,
scope_
)
}
}
}
})
}
}
export function handleValue(
target: any,
handledSet: Set<any>,
rootScope: ImmerScope
) {
if (!rootScope.immer_.autoFreeze_ && rootScope.unfinalizedDrafts_ < 1) {
// optimization: if an object is not a draft, and we don't have to
// deepfreeze everything, and we are sure that no drafts are left in the remaining object
// cause we saw and finalized all drafts already; we can stop visiting the rest of the tree.
// This benefits especially adding large data tree's without further processing.
// See add-data.js perf test
return target
}
// Skip if already handled, frozen, or not draftable
if (
isDraft(target) ||
handledSet.has(target) ||
!isDraftable(target) ||
isFrozen(target)
) {
return target
}
handledSet.add(target)
// Process ALL properties/entries
each(target, (key, value) => {
if (isDraft(value)) {
const state: ImmerState = value[DRAFT_STATE]
if (isSameScope(state, rootScope)) {
// Replace draft with finalized value
const updatedValue = getFinalValue(state)
set(target, key, updatedValue, target.type_)
markStateFinalized(state)
}
} else if (isDraftable(value)) {
// Recursively handle nested values
handleValue(value, handledSet, rootScope)
}
})
return target
}

273
frontend/node_modules/immer/src/core/immerClass.ts generated vendored Normal file
View File

@@ -0,0 +1,273 @@
import {
IProduceWithPatches,
IProduce,
ImmerState,
Drafted,
isDraftable,
processResult,
Patch,
Objectish,
DRAFT_STATE,
Draft,
PatchListener,
isDraft,
isMap,
isSet,
createProxyProxy,
getPlugin,
die,
enterScope,
revokeScope,
leaveScope,
usePatchesInScope,
getCurrentScope,
NOTHING,
freeze,
current,
ImmerScope,
registerChildFinalizationCallback,
ArchType,
MapSetPlugin,
AnyMap,
AnySet,
isObjectish,
isFunction,
isBoolean,
PluginMapSet,
PluginPatches
} from "../internal"
interface ProducersFns {
produce: IProduce
produceWithPatches: IProduceWithPatches
}
export type StrictMode = boolean | "class_only"
export class Immer implements ProducersFns {
autoFreeze_: boolean = true
useStrictShallowCopy_: StrictMode = false
useStrictIteration_: boolean = false
constructor(config?: {
autoFreeze?: boolean
useStrictShallowCopy?: StrictMode
useStrictIteration?: boolean
}) {
if (isBoolean(config?.autoFreeze)) this.setAutoFreeze(config!.autoFreeze)
if (isBoolean(config?.useStrictShallowCopy))
this.setUseStrictShallowCopy(config!.useStrictShallowCopy)
if (isBoolean(config?.useStrictIteration))
this.setUseStrictIteration(config!.useStrictIteration)
}
/**
* The `produce` function takes a value and a "recipe function" (whose
* return value often depends on the base state). The recipe function is
* free to mutate its first argument however it wants. All mutations are
* only ever applied to a __copy__ of the base state.
*
* Pass only a function to create a "curried producer" which relieves you
* from passing the recipe function every time.
*
* Only plain objects and arrays are made mutable. All other objects are
* considered uncopyable.
*
* Note: This function is __bound__ to its `Immer` instance.
*
* @param {any} base - the initial state
* @param {Function} recipe - function that receives a proxy of the base state as first argument and which can be freely modified
* @param {Function} patchListener - optional function that will be called with all the patches produced here
* @returns {any} a new state, or the initial state if nothing was modified
*/
produce: IProduce = (base: any, recipe?: any, patchListener?: any) => {
// curried invocation
if (isFunction(base) && !isFunction(recipe)) {
const defaultBase = recipe
recipe = base
const self = this
return function curriedProduce(
this: any,
base = defaultBase,
...args: any[]
) {
return self.produce(base, (draft: Drafted) => recipe.call(this, draft, ...args)) // prettier-ignore
}
}
if (!isFunction(recipe)) die(6)
if (patchListener !== undefined && !isFunction(patchListener)) die(7)
let result
// Only plain objects, arrays, and "immerable classes" are drafted.
if (isDraftable(base)) {
const scope = enterScope(this)
const proxy = createProxy(scope, base, undefined)
let hasError = true
try {
result = recipe(proxy)
hasError = false
} finally {
// finally instead of catch + rethrow better preserves original stack
if (hasError) revokeScope(scope)
else leaveScope(scope)
}
usePatchesInScope(scope, patchListener)
return processResult(result, scope)
} else if (!base || !isObjectish(base)) {
result = recipe(base)
if (result === undefined) result = base
if (result === NOTHING) result = undefined
if (this.autoFreeze_) freeze(result, true)
if (patchListener) {
const p: Patch[] = []
const ip: Patch[] = []
getPlugin(PluginPatches).generateReplacementPatches_(base, result, {
patches_: p,
inversePatches_: ip
} as ImmerScope) // dummy scope
patchListener(p, ip)
}
return result
} else die(1, base)
}
produceWithPatches: IProduceWithPatches = (base: any, recipe?: any): any => {
// curried invocation
if (isFunction(base)) {
return (state: any, ...args: any[]) =>
this.produceWithPatches(state, (draft: any) => base(draft, ...args))
}
let patches: Patch[], inversePatches: Patch[]
const result = this.produce(base, recipe, (p: Patch[], ip: Patch[]) => {
patches = p
inversePatches = ip
})
return [result, patches!, inversePatches!]
}
createDraft<T extends Objectish>(base: T): Draft<T> {
if (!isDraftable(base)) die(8)
if (isDraft(base)) base = current(base)
const scope = enterScope(this)
const proxy = createProxy(scope, base, undefined)
proxy[DRAFT_STATE].isManual_ = true
leaveScope(scope)
return proxy as any
}
finishDraft<D extends Draft<any>>(
draft: D,
patchListener?: PatchListener
): D extends Draft<infer T> ? T : never {
const state: ImmerState = draft && (draft as any)[DRAFT_STATE]
if (!state || !state.isManual_) die(9)
const {scope_: scope} = state
usePatchesInScope(scope, patchListener)
return processResult(undefined, scope)
}
/**
* Pass true to automatically freeze all copies created by Immer.
*
* By default, auto-freezing is enabled.
*/
setAutoFreeze(value: boolean) {
this.autoFreeze_ = value
}
/**
* Pass true to enable strict shallow copy.
*
* By default, immer does not copy the object descriptors such as getter, setter and non-enumrable properties.
*/
setUseStrictShallowCopy(value: StrictMode) {
this.useStrictShallowCopy_ = value
}
/**
* Pass false to use faster iteration that skips non-enumerable properties
* but still handles symbols for compatibility.
*
* By default, strict iteration is enabled (includes all own properties).
*/
setUseStrictIteration(value: boolean) {
this.useStrictIteration_ = value
}
shouldUseStrictIteration(): boolean {
return this.useStrictIteration_
}
applyPatches<T extends Objectish>(base: T, patches: readonly Patch[]): T {
// If a patch replaces the entire state, take that replacement as base
// before applying patches
let i: number
for (i = patches.length - 1; i >= 0; i--) {
const patch = patches[i]
if (patch.path.length === 0 && patch.op === "replace") {
base = patch.value
break
}
}
// If there was a patch that replaced the entire state, start from the
// patch after that.
if (i > -1) {
patches = patches.slice(i + 1)
}
const applyPatchesImpl = getPlugin(PluginPatches).applyPatches_
if (isDraft(base)) {
// N.B: never hits if some patch a replacement, patches are never drafts
return applyPatchesImpl(base, patches)
}
// Otherwise, produce a copy of the base state.
return this.produce(base, (draft: Drafted) =>
applyPatchesImpl(draft, patches)
)
}
}
export function createProxy<T extends Objectish>(
rootScope: ImmerScope,
value: T,
parent?: ImmerState,
key?: string | number | symbol
): Drafted<T, ImmerState> {
// precondition: createProxy should be guarded by isDraftable, so we know we can safely draft
// returning a tuple here lets us skip a proxy access
// to DRAFT_STATE later
const [draft, state] = isMap(value)
? getPlugin(PluginMapSet).proxyMap_(value, parent)
: isSet(value)
? getPlugin(PluginMapSet).proxySet_(value, parent)
: createProxyProxy(value, parent)
const scope = parent?.scope_ ?? getCurrentScope()
scope.drafts_.push(draft)
// Ensure the parent callbacks are passed down so we actually
// track all callbacks added throughout the tree
state.callbacks_ = parent?.callbacks_ ?? []
state.key_ = key
if (parent && key !== undefined) {
registerChildFinalizationCallback(parent, state, key)
} else {
// It's a root draft, register it with the scope
state.callbacks_.push(function rootDraftCleanup(rootScope) {
rootScope.mapSetPlugin_?.fixSetContents(state)
const {patchPlugin_} = rootScope
if (state.modified_ && patchPlugin_) {
patchPlugin_.generatePatches_(state, [], rootScope)
}
})
}
return draft as any
}

336
frontend/node_modules/immer/src/core/proxy.ts generated vendored Normal file
View File

@@ -0,0 +1,336 @@
import {
has,
is,
isDraftable,
shallowCopy,
latest,
ImmerBaseState,
ImmerState,
Drafted,
AnyObject,
AnyArray,
Objectish,
getCurrentScope,
getPrototypeOf,
DRAFT_STATE,
die,
createProxy,
ArchType,
handleCrossReference,
WRITABLE,
CONFIGURABLE,
ENUMERABLE,
VALUE,
isArray,
isArrayIndex
} from "../internal"
interface ProxyBaseState extends ImmerBaseState {
parent_?: ImmerState
revoke_(): void
}
export interface ProxyObjectState extends ProxyBaseState {
type_: ArchType.Object
base_: any
copy_: any
draft_: Drafted<AnyObject, ProxyObjectState>
}
export interface ProxyArrayState extends ProxyBaseState {
type_: ArchType.Array
base_: AnyArray
copy_: AnyArray | null
draft_: Drafted<AnyArray, ProxyArrayState>
operationMethod?: string
allIndicesReassigned_?: boolean
}
type ProxyState = ProxyObjectState | ProxyArrayState
/**
* Returns a new draft of the `base` object.
*
* The second argument is the parent draft-state (used internally).
*/
export function createProxyProxy<T extends Objectish>(
base: T,
parent?: ImmerState
): [Drafted<T, ProxyState>, ProxyState] {
const baseIsArray = isArray(base)
const state: ProxyState = {
type_: baseIsArray ? ArchType.Array : (ArchType.Object as any),
// Track which produce call this is associated with.
scope_: parent ? parent.scope_ : getCurrentScope()!,
// True for both shallow and deep changes.
modified_: false,
// Used during finalization.
finalized_: false,
// Track which properties have been assigned (true) or deleted (false).
// actually instantiated in `prepareCopy()`
assigned_: undefined,
// The parent draft state.
parent_: parent,
// The base state.
base_: base,
// The base proxy.
draft_: null as any, // set below
// The base copy with any updated values.
copy_: null,
// Called by the `produce` function.
revoke_: null as any,
isManual_: false,
// `callbacks` actually gets assigned in `createProxy`
callbacks_: undefined as any
}
// the traps must target something, a bit like the 'real' base.
// but also, we need to be able to determine from the target what the relevant state is
// (to avoid creating traps per instance to capture the state in closure,
// and to avoid creating weird hidden properties as well)
// So the trick is to use 'state' as the actual 'target'! (and make sure we intercept everything)
// Note that in the case of an array, we put the state in an array to have better Reflect defaults ootb
let target: T = state as any
let traps: ProxyHandler<object | Array<any>> = objectTraps
if (baseIsArray) {
target = [state] as any
traps = arrayTraps
}
const {revoke, proxy} = Proxy.revocable(target, traps)
state.draft_ = proxy as any
state.revoke_ = revoke
return [proxy as any, state]
}
/**
* Object drafts
*/
export const objectTraps: ProxyHandler<ProxyState> = {
get(state, prop) {
if (prop === DRAFT_STATE) return state
let arrayPlugin = state.scope_.arrayMethodsPlugin_
const isArrayWithStringProp =
state.type_ === ArchType.Array && typeof prop === "string"
// Intercept array methods so that we can override
// behavior and skip proxy creation for perf
if (isArrayWithStringProp) {
if (arrayPlugin?.isArrayOperationMethod(prop)) {
return arrayPlugin.createMethodInterceptor(state, prop)
}
}
const source = latest(state)
if (!has(source, prop, state.type_)) {
// non-existing or non-own property...
return readPropFromProto(state, source, prop)
}
const value = source[prop]
if (state.finalized_ || !isDraftable(value)) {
return value
}
// During mutating array operations, defer proxy creation for array elements
// This optimization avoids creating unnecessary proxies during sort/reverse
if (
isArrayWithStringProp &&
(state as ProxyArrayState).operationMethod &&
arrayPlugin?.isMutatingArrayMethod(
(state as ProxyArrayState).operationMethod!
) &&
isArrayIndex(prop)
) {
// Return raw value during mutating operations, create proxy only if modified
return value
}
// Check for existing draft in modified state.
// Assigned values are never drafted. This catches any drafts we created, too.
if (value === peek(state.base_, prop)) {
prepareCopy(state)
// Ensure array keys are always numbers
const childKey = state.type_ === ArchType.Array ? +(prop as string) : prop
const childDraft = createProxy(state.scope_, value, state, childKey)
return (state.copy_![childKey] = childDraft)
}
return value
},
has(state, prop) {
return prop in latest(state)
},
ownKeys(state) {
return Reflect.ownKeys(latest(state))
},
set(
state: ProxyObjectState,
prop: string /* strictly not, but helps TS */,
value
) {
const desc = getDescriptorFromProto(latest(state), prop)
if (desc?.set) {
// special case: if this write is captured by a setter, we have
// to trigger it with the correct context
desc.set.call(state.draft_, value)
return true
}
if (!state.modified_) {
// the last check is because we need to be able to distinguish setting a non-existing to undefined (which is a change)
// from setting an existing property with value undefined to undefined (which is not a change)
const current = peek(latest(state), prop)
// special case, if we assigning the original value to a draft, we can ignore the assignment
const currentState: ProxyObjectState = current?.[DRAFT_STATE]
if (currentState && currentState.base_ === value) {
state.copy_![prop] = value
state.assigned_!.set(prop, false)
return true
}
if (
is(value, current) &&
(value !== undefined || has(state.base_, prop, state.type_))
)
return true
prepareCopy(state)
markChanged(state)
}
if (
(state.copy_![prop] === value &&
// special case: handle new props with value 'undefined'
(value !== undefined || prop in state.copy_)) ||
// special case: NaN
(Number.isNaN(value) && Number.isNaN(state.copy_![prop]))
)
return true
// @ts-ignore
state.copy_![prop] = value
state.assigned_!.set(prop, true)
handleCrossReference(state, prop, value)
return true
},
deleteProperty(state, prop: string) {
prepareCopy(state)
// The `undefined` check is a fast path for pre-existing keys.
if (peek(state.base_, prop) !== undefined || prop in state.base_) {
state.assigned_!.set(prop, false)
markChanged(state)
} else {
// if an originally not assigned property was deleted
state.assigned_!.delete(prop)
}
if (state.copy_) {
delete state.copy_[prop]
}
return true
},
// Note: We never coerce `desc.value` into an Immer draft, because we can't make
// the same guarantee in ES5 mode.
getOwnPropertyDescriptor(state, prop) {
const owner = latest(state)
const desc = Reflect.getOwnPropertyDescriptor(owner, prop)
if (!desc) return desc
return {
[WRITABLE]: true,
[CONFIGURABLE]: state.type_ !== ArchType.Array || prop !== "length",
[ENUMERABLE]: desc[ENUMERABLE],
[VALUE]: owner[prop]
}
},
defineProperty() {
die(11)
},
getPrototypeOf(state) {
return getPrototypeOf(state.base_)
},
setPrototypeOf() {
die(12)
}
}
/**
* Array drafts
*/
const arrayTraps: ProxyHandler<[ProxyArrayState]> = {}
// Use `for..in` instead of `each` to work around a weird
// prod test suite issue
for (let key in objectTraps) {
let fn = objectTraps[key as keyof typeof objectTraps] as Function
// @ts-ignore
arrayTraps[key] = function() {
const args = arguments
args[0] = args[0][0]
return fn.apply(this, args)
}
}
arrayTraps.deleteProperty = function(state, prop) {
if (process.env.NODE_ENV !== "production" && isNaN(parseInt(prop as any)))
die(13)
// @ts-ignore
return arrayTraps.set!.call(this, state, prop, undefined)
}
arrayTraps.set = function(state, prop, value) {
if (
process.env.NODE_ENV !== "production" &&
prop !== "length" &&
isNaN(parseInt(prop as any))
)
die(14)
return objectTraps.set!.call(this, state[0], prop, value, state[0])
}
// Access a property without creating an Immer draft.
function peek(draft: Drafted, prop: PropertyKey) {
const state = draft[DRAFT_STATE]
const source = state ? latest(state) : draft
return source[prop]
}
function readPropFromProto(state: ImmerState, source: any, prop: PropertyKey) {
const desc = getDescriptorFromProto(source, prop)
return desc
? VALUE in desc
? desc[VALUE]
: // This is a very special case, if the prop is a getter defined by the
// prototype, we should invoke it with the draft as context!
desc.get?.call(state.draft_)
: undefined
}
function getDescriptorFromProto(
source: any,
prop: PropertyKey
): PropertyDescriptor | undefined {
// 'in' checks proto!
if (!(prop in source)) return undefined
let proto = getPrototypeOf(source)
while (proto) {
const desc = Object.getOwnPropertyDescriptor(proto, prop)
if (desc) return desc
proto = getPrototypeOf(proto)
}
return undefined
}
export function markChanged(state: ImmerState) {
if (!state.modified_) {
state.modified_ = true
if (state.parent_) {
markChanged(state.parent_)
}
}
}
export function prepareCopy(state: ImmerState) {
if (!state.copy_) {
// Actually create the `assigned_` map now that we
// know this is a modified draft.
state.assigned_ = new Map()
state.copy_ = shallowCopy(
state.base_,
state.scope_.immer_.useStrictShallowCopy_
)
}
}

95
frontend/node_modules/immer/src/core/scope.ts generated vendored Normal file
View File

@@ -0,0 +1,95 @@
import {
Patch,
PatchListener,
Drafted,
Immer,
DRAFT_STATE,
ImmerState,
ArchType,
getPlugin,
PatchesPlugin,
MapSetPlugin,
isPluginLoaded,
PluginMapSet,
PluginPatches,
ArrayMethodsPlugin,
PluginArrayMethods
} from "../internal"
/** Each scope represents a `produce` call. */
export interface ImmerScope {
patches_?: Patch[]
inversePatches_?: Patch[]
patchPlugin_?: PatchesPlugin
mapSetPlugin_?: MapSetPlugin
arrayMethodsPlugin_?: ArrayMethodsPlugin
canAutoFreeze_: boolean
drafts_: any[]
parent_?: ImmerScope
patchListener_?: PatchListener
immer_: Immer
unfinalizedDrafts_: number
handledSet_: Set<any>
processedForPatches_: Set<any>
}
let currentScope: ImmerScope | undefined
export let getCurrentScope = () => currentScope!
let createScope = (
parent_: ImmerScope | undefined,
immer_: Immer
): ImmerScope => ({
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,
handledSet_: new Set(),
processedForPatches_: new Set(),
mapSetPlugin_: isPluginLoaded(PluginMapSet)
? getPlugin(PluginMapSet)
: undefined,
arrayMethodsPlugin_: isPluginLoaded(PluginArrayMethods)
? getPlugin(PluginArrayMethods)
: undefined
})
export function usePatchesInScope(
scope: ImmerScope,
patchListener?: PatchListener
) {
if (patchListener) {
scope.patchPlugin_ = getPlugin(PluginPatches) // 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 let enterScope = (immer: Immer) =>
(currentScope = createScope(currentScope, immer))
function revokeDraft(draft: Drafted) {
const state: ImmerState = draft[DRAFT_STATE]
if (state.type_ === ArchType.Object || state.type_ === ArchType.Array)
state.revoke_()
else state.revoked_ = true
}

126
frontend/node_modules/immer/src/immer.ts generated vendored Normal file
View File

@@ -0,0 +1,126 @@
import {
IProduce,
IProduceWithPatches,
Immer,
Draft,
Immutable
} from "./internal"
export {
Draft,
WritableDraft,
Immutable,
Patch,
PatchListener,
Producer,
original,
current,
isDraft,
isDraftable,
NOTHING as nothing,
DRAFTABLE as immerable,
freeze,
Objectish,
StrictMode
} from "./internal"
const immer = new Immer()
/**
* The `produce` function takes a value and a "recipe function" (whose
* return value often depends on the base state). The recipe function is
* free to mutate its first argument however it wants. All mutations are
* only ever applied to a __copy__ of the base state.
*
* Pass only a function to create a "curried producer" which relieves you
* from passing the recipe function every time.
*
* Only plain objects and arrays are made mutable. All other objects are
* considered uncopyable.
*
* Note: This function is __bound__ to its `Immer` instance.
*
* @param {any} base - the initial state
* @param {Function} producer - function that receives a proxy of the base state as first argument and which can be freely modified
* @param {Function} patchListener - optional function that will be called with all the patches produced here
* @returns {any} a new state, or the initial state if nothing was modified
*/
export const produce: IProduce = /* @__PURE__ */ immer.produce
/**
* Like `produce`, but `produceWithPatches` always returns a tuple
* [nextState, patches, inversePatches] (instead of just the next state)
*/
export const produceWithPatches: IProduceWithPatches = /* @__PURE__ */ immer.produceWithPatches.bind(
immer
)
/**
* Pass true to automatically freeze all copies created by Immer.
*
* Always freeze by default, even in production mode
*/
export const setAutoFreeze = /* @__PURE__ */ immer.setAutoFreeze.bind(immer)
/**
* Pass true to enable strict shallow copy.
*
* By default, immer does not copy the object descriptors such as getter, setter and non-enumrable properties.
*/
export const setUseStrictShallowCopy = /* @__PURE__ */ immer.setUseStrictShallowCopy.bind(
immer
)
/**
* Pass false to use loose iteration that only processes enumerable string properties.
* This skips symbols and non-enumerable properties for maximum performance.
*
* By default, strict iteration is enabled (includes all own properties).
*/
export const setUseStrictIteration = /* @__PURE__ */ immer.setUseStrictIteration.bind(
immer
)
/**
* Apply an array of Immer patches to the first argument.
*
* This function is a producer, which means copy-on-write is in effect.
*/
export const applyPatches = /* @__PURE__ */ immer.applyPatches.bind(immer)
/**
* Create an Immer draft from the given base state, which may be a draft itself.
* The draft can be modified until you finalize it with the `finishDraft` function.
*/
export const createDraft = /* @__PURE__ */ immer.createDraft.bind(immer)
/**
* Finalize an Immer draft from a `createDraft` call, returning the base state
* (if no changes were made) or a modified copy. The draft must *not* be
* mutated afterwards.
*
* Pass a function as the 2nd argument to generate Immer patches based on the
* changes that were made.
*/
export const finishDraft = /* @__PURE__ */ immer.finishDraft.bind(immer)
/**
* This function is actually a no-op, but can be used to cast an immutable type
* to an draft type and make TypeScript happy
*
* @param value
*/
export let castDraft = <T>(value: T): Draft<T> => value as any
/**
* This function is actually a no-op, but can be used to cast a mutable type
* to an immutable type and make TypeScript happy
* @param value
*/
export let castImmutable = <T>(value: T): Immutable<T> => value as any
export {Immer}
export {enablePatches} from "./plugins/patches"
export {enableMapSet} from "./plugins/mapset"
export {enableArrayMethods} from "./plugins/arrayMethods"

11
frontend/node_modules/immer/src/internal.ts generated vendored Normal file
View File

@@ -0,0 +1,11 @@
export * from "./utils/env"
export * from "./utils/errors"
export * from "./types/types-external"
export * from "./types/types-internal"
export * from "./utils/common"
export * from "./utils/plugins"
export * from "./core/scope"
export * from "./core/finalize"
export * from "./core/proxy"
export * from "./core/immerClass"
export * from "./core/current"

440
frontend/node_modules/immer/src/plugins/arrayMethods.ts generated vendored Normal file
View File

@@ -0,0 +1,440 @@
import {
PluginArrayMethods,
latest,
loadPlugin,
markChanged,
prepareCopy,
handleCrossReference,
ProxyArrayState
} from "../internal"
/**
* Methods that directly modify the array in place.
* These operate on the copy without creating per-element proxies:
* - `push`, `pop`: Add/remove from end
* - `shift`, `unshift`: Add/remove from start (marks all indices reassigned)
* - `splice`: Add/remove at arbitrary position (marks all indices reassigned)
* - `reverse`, `sort`: Reorder elements (marks all indices reassigned)
*/
type MutatingArrayMethod =
| "push"
| "pop"
| "shift"
| "unshift"
| "splice"
| "reverse"
| "sort"
/**
* Methods that read from the array without modifying it.
* These fall into distinct categories based on return semantics:
*
* **Subset operations** (return drafts - mutations propagate):
* - `filter`, `slice`: Return array of draft proxies
* - `find`, `findLast`: Return single draft proxy or undefined
*
* **Transform operations** (return base values - mutations don't track):
* - `concat`, `flat`: Create new structures, not subsets of original
*
* **Primitive-returning** (no draft needed):
* - `findIndex`, `findLastIndex`, `indexOf`, `lastIndexOf`: Return numbers
* - `some`, `every`, `includes`: Return booleans
* - `join`, `toString`, `toLocaleString`: Return strings
*/
type NonMutatingArrayMethod =
| "filter"
| "slice"
| "concat"
| "flat"
| "find"
| "findIndex"
| "findLast"
| "findLastIndex"
| "some"
| "every"
| "indexOf"
| "lastIndexOf"
| "includes"
| "join"
| "toString"
| "toLocaleString"
/** Union of all array operation methods handled by the plugin. */
export type ArrayOperationMethod = MutatingArrayMethod | NonMutatingArrayMethod
/**
* Enables optimized array method handling for Immer drafts.
*
* This plugin overrides array methods to avoid unnecessary Proxy creation during iteration,
* significantly improving performance for array-heavy operations.
*
* **Mutating methods** (push, pop, shift, unshift, splice, sort, reverse):
* Operate directly on the copy without creating per-element proxies.
*
* **Non-mutating methods** fall into categories:
* - **Subset operations** (filter, slice, find, findLast): Return draft proxies - mutations track
* - **Transform operations** (concat, flat): Return base values - mutations don't track
* - **Primitive-returning** (indexOf, includes, some, every, etc.): Return primitives
*
* **Important**: Callbacks for overridden methods receive base values, not drafts.
* This is the core performance optimization.
*
* @example
* ```ts
* import { enableArrayMethods, produce } from "immer"
*
* enableArrayMethods()
*
* const next = produce(state, draft => {
* // Optimized - no proxy creation per element
* draft.items.sort((a, b) => a.value - b.value)
*
* // filter returns drafts - mutations propagate
* const filtered = draft.items.filter(x => x.value > 5)
* filtered[0].value = 999 // Affects draft.items[originalIndex]
* })
* ```
*
* @see https://immerjs.github.io/immer/array-methods
*/
export function enableArrayMethods() {
const SHIFTING_METHODS = new Set<MutatingArrayMethod>(["shift", "unshift"])
const QUEUE_METHODS = new Set<MutatingArrayMethod>(["push", "pop"])
const RESULT_RETURNING_METHODS = new Set<MutatingArrayMethod>([
...QUEUE_METHODS,
...SHIFTING_METHODS
])
const REORDERING_METHODS = new Set<MutatingArrayMethod>(["reverse", "sort"])
// Optimized method detection using array-based lookup
const MUTATING_METHODS = new Set<MutatingArrayMethod>([
...RESULT_RETURNING_METHODS,
...REORDERING_METHODS,
"splice"
])
const FIND_METHODS = new Set<NonMutatingArrayMethod>(["find", "findLast"])
const NON_MUTATING_METHODS = new Set<NonMutatingArrayMethod>([
"filter",
"slice",
"concat",
"flat",
...FIND_METHODS,
"findIndex",
"findLastIndex",
"some",
"every",
"indexOf",
"lastIndexOf",
"includes",
"join",
"toString",
"toLocaleString"
])
// Type guard for method detection
function isMutatingArrayMethod(
method: string
): method is MutatingArrayMethod {
return MUTATING_METHODS.has(method as any)
}
function isNonMutatingArrayMethod(
method: string
): method is NonMutatingArrayMethod {
return NON_MUTATING_METHODS.has(method as any)
}
function isArrayOperationMethod(
method: string
): method is ArrayOperationMethod {
return isMutatingArrayMethod(method) || isNonMutatingArrayMethod(method)
}
function enterOperation(
state: ProxyArrayState,
method: ArrayOperationMethod
) {
state.operationMethod = method
}
function exitOperation(state: ProxyArrayState) {
state.operationMethod = undefined
}
// Shared utility functions for array method handlers
function executeArrayMethod<T>(
state: ProxyArrayState,
operation: () => T,
markLength = true
): T {
prepareCopy(state)
const result = operation()
markChanged(state)
if (markLength) state.assigned_!.set("length", true)
return result
}
function markAllIndicesReassigned(state: ProxyArrayState) {
state.allIndicesReassigned_ = true
}
function normalizeSliceIndex(index: number, length: number): number {
if (index < 0) {
return Math.max(length + index, 0)
}
return Math.min(index, length)
}
/**
* Calls handleCrossReference for each value being inserted into the array,
* and marks the corresponding indices as assigned in `assigned_`.
*
* This ensures nested drafts inside inserted values (e.g. from spreading
* a draft object) are properly finalized, matching the behavior of the
* proxy set trap which calls handleCrossReference on every assignment.
*
* Without this, values containing draft proxies (like `{...state[0]}`)
* pushed via the array methods plugin would have their nested drafts
* revoked during finalization without being replaced by final values.
*/
function handleInsertedValues(
state: ProxyArrayState,
startIndex: number,
values: any[]
) {
for (let i = 0; i < values.length; i++) {
const index = startIndex + i
state.assigned_!.set(index, true)
handleCrossReference(state, index, values[i])
}
}
/**
* Handles mutating operations that add/remove elements (push, pop, shift, unshift, splice).
*
* Operates directly on `state.copy_` without creating per-element proxies.
* For shifting methods (shift, unshift), marks all indices as reassigned since
* indices shift.
*
* @returns For push/pop/shift/unshift: the native method result. For others: the draft.
*/
function handleSimpleOperation(
state: ProxyArrayState,
method: string,
args: any[]
) {
return executeArrayMethod(state, () => {
// For push/unshift, capture the length before the operation
// so we can compute insertion indices for handleCrossReference
const lengthBefore = state.copy_!.length
const result = (state.copy_! as any)[method](...args)
// Handle index reassignment for shifting methods
if (SHIFTING_METHODS.has(method as MutatingArrayMethod)) {
markAllIndicesReassigned(state)
}
// Handle cross-references for newly inserted values.
// push appends at the end, unshift inserts at the beginning.
if (method === "push" && args.length > 0) {
handleInsertedValues(state, lengthBefore, args)
} else if (method === "unshift" && args.length > 0) {
handleInsertedValues(state, 0, args)
}
// Return appropriate value based on method
return RESULT_RETURNING_METHODS.has(method as MutatingArrayMethod)
? result
: state.draft_
})
}
/**
* Handles reordering operations (reverse, sort) that change element order.
*
* Operates directly on `state.copy_` and marks all indices as reassigned
* since element positions change. Does not mark length as changed since
* these operations preserve array length.
*
* @returns The draft proxy for method chaining.
*/
function handleReorderingOperation(
state: ProxyArrayState,
method: string,
args: any[]
) {
return executeArrayMethod(
state,
() => {
;(state.copy_! as any)[method](...args)
markAllIndicesReassigned(state)
return state.draft_
},
false
) // Don't mark length as changed
}
/**
* Creates an interceptor function for a specific array method.
*
* The interceptor wraps array method calls to:
* 1. Set `state.operationMethod` flag during execution (allows proxy `get` trap
* to detect we're inside an optimized method and skip proxy creation)
* 2. Route to appropriate handler based on method type
* 3. Clean up the operation flag in `finally` block
*
* The `operationMethod` flag is the key mechanism that enables the proxy's `get`
* trap to return base values instead of creating nested proxies during iteration.
*
* @param state - The proxy array state
* @param originalMethod - Name of the array method being intercepted
* @returns Interceptor function that handles the method call
*/
function createMethodInterceptor(
state: ProxyArrayState,
originalMethod: string
) {
return function interceptedMethod(...args: any[]) {
// Enter operation mode - this flag tells the proxy's get trap to return
// base values instead of creating nested proxies during iteration
const method = originalMethod as ArrayOperationMethod
enterOperation(state, method)
try {
// Check if this is a mutating method
if (isMutatingArrayMethod(method)) {
// Direct method dispatch - no configuration lookup needed
if (RESULT_RETURNING_METHODS.has(method)) {
return handleSimpleOperation(state, method, args)
}
if (REORDERING_METHODS.has(method)) {
return handleReorderingOperation(state, method, args)
}
if (method === "splice") {
const res = executeArrayMethod(state, () =>
state.copy_!.splice(...(args as [number, number, ...any[]]))
)
markAllIndicesReassigned(state)
// Handle cross-references for inserted values (args from index 2+)
if (args.length > 2) {
const startIndex = normalizeSliceIndex(
args[0] ?? 0,
state.copy_!.length
)
handleInsertedValues(state, startIndex, args.slice(2))
}
return res
}
} else {
// Handle non-mutating methods
return handleNonMutatingOperation(state, method, args)
}
} finally {
// Always exit operation mode - must be in finally to handle exceptions
exitOperation(state)
}
}
}
/**
* Handles non-mutating array methods with different return semantics.
*
* **Subset operations** return draft proxies for mutation tracking:
* - `filter`, `slice`: Return `state.draft_[i]` for each selected element
* - `find`, `findLast`: Return `state.draft_[i]` for the found element
*
* This allows mutations on returned elements to propagate back to the draft:
* ```ts
* const filtered = draft.items.filter(x => x.value > 5)
* filtered[0].value = 999 // Mutates draft.items[originalIndex]
* ```
*
* **Transform operations** return base values (no draft tracking):
* - `concat`, `flat`: These create NEW arrays rather than selecting subsets.
* Since the result structure differs from the original, tracking mutations
* back to specific draft indices would be impractical/impossible.
*
* **Primitive operations** return the native result directly:
* - `indexOf`, `includes`, `some`, `every`, `join`, etc.
*
* @param state - The proxy array state
* @param method - The non-mutating method name
* @param args - Arguments passed to the method
* @returns Drafts for subset operations, base values for transforms, primitives otherwise
*/
function handleNonMutatingOperation(
state: ProxyArrayState,
method: NonMutatingArrayMethod,
args: any[]
) {
const source = latest(state)
// Methods that return arrays with selected items - need to return drafts
if (method === "filter") {
const predicate = args[0]
const result: any[] = []
// First pass: call predicate on base values to determine which items pass
for (let i = 0; i < source.length; i++) {
if (predicate(source[i], i, source)) {
// Only create draft for items that passed the predicate
result.push(state.draft_[i])
}
}
return result
}
if (FIND_METHODS.has(method)) {
const predicate = args[0]
const isForward = method === "find"
const step = isForward ? 1 : -1
const start = isForward ? 0 : source.length - 1
for (let i = start; i >= 0 && i < source.length; i += step) {
if (predicate(source[i], i, source)) {
return state.draft_[i]
}
}
return undefined
}
if (method === "slice") {
const rawStart = args[0] ?? 0
const rawEnd = args[1] ?? source.length
// Normalize negative indices
const start = normalizeSliceIndex(rawStart, source.length)
const end = normalizeSliceIndex(rawEnd, source.length)
const result: any[] = []
// Return drafts for items in the slice range
for (let i = start; i < end; i++) {
result.push(state.draft_[i])
}
return result
}
// For other methods, call on base array directly:
// - indexOf, includes, join, toString: Return primitives, no draft needed
// - concat, flat: Return NEW arrays (not subsets). Elements are base values.
// This is intentional - concat/flat create new data structures rather than
// selecting subsets of the original, making draft tracking impractical.
return source[method as keyof typeof Array.prototype](...args)
}
loadPlugin(PluginArrayMethods, {
createMethodInterceptor,
isArrayOperationMethod,
isMutatingArrayMethod
})
}

332
frontend/node_modules/immer/src/plugins/mapset.ts generated vendored Normal file
View File

@@ -0,0 +1,332 @@
// types only!
import {
ImmerState,
AnyMap,
AnySet,
MapState,
SetState,
DRAFT_STATE,
getCurrentScope,
latest,
isDraftable,
createProxy,
loadPlugin,
markChanged,
die,
ArchType,
each,
getValue,
PluginMapSet,
handleCrossReference
} from "../internal"
export function enableMapSet() {
class DraftMap extends Map {
[DRAFT_STATE]: MapState
constructor(target: AnyMap, parent?: ImmerState) {
super()
this[DRAFT_STATE] = {
type_: ArchType.Map,
parent_: parent,
scope_: parent ? parent.scope_ : getCurrentScope()!,
modified_: false,
finalized_: false,
copy_: undefined,
assigned_: undefined,
base_: target,
draft_: this as any,
isManual_: false,
revoked_: false,
callbacks_: []
}
}
get size(): number {
return latest(this[DRAFT_STATE]).size
}
has(key: any): boolean {
return latest(this[DRAFT_STATE]).has(key)
}
set(key: any, value: any) {
const state: MapState = this[DRAFT_STATE]
assertUnrevoked(state)
if (!latest(state).has(key) || latest(state).get(key) !== value) {
prepareMapCopy(state)
markChanged(state)
state.assigned_!.set(key, true)
state.copy_!.set(key, value)
state.assigned_!.set(key, true)
handleCrossReference(state, key, value)
}
return this
}
delete(key: any): boolean {
if (!this.has(key)) {
return false
}
const state: MapState = this[DRAFT_STATE]
assertUnrevoked(state)
prepareMapCopy(state)
markChanged(state)
if (state.base_.has(key)) {
state.assigned_!.set(key, false)
} else {
state.assigned_!.delete(key)
}
state.copy_!.delete(key)
return true
}
clear() {
const state: MapState = this[DRAFT_STATE]
assertUnrevoked(state)
if (latest(state).size) {
prepareMapCopy(state)
markChanged(state)
state.assigned_ = new Map()
each(state.base_, key => {
state.assigned_!.set(key, false)
})
state.copy_!.clear()
}
}
forEach(cb: (value: any, key: any, self: any) => void, thisArg?: any) {
const state: MapState = this[DRAFT_STATE]
latest(state).forEach((_value: any, key: any, _map: any) => {
cb.call(thisArg, this.get(key), key, this)
})
}
get(key: any): any {
const state: MapState = this[DRAFT_STATE]
assertUnrevoked(state)
const value = latest(state).get(key)
if (state.finalized_ || !isDraftable(value)) {
return value
}
if (value !== state.base_.get(key)) {
return value // either already drafted or reassigned
}
// despite what it looks, this creates a draft only once, see above condition
const draft = createProxy(state.scope_, value, state, key)
prepareMapCopy(state)
state.copy_!.set(key, draft)
return draft
}
keys(): IterableIterator<any> {
return latest(this[DRAFT_STATE]).keys()
}
values(): IterableIterator<any> {
const iterator = this.keys()
return {
[Symbol.iterator]: () => this.values(),
next: () => {
const r = iterator.next()
/* istanbul ignore next */
if (r.done) return r
const value = this.get(r.value)
return {
done: false,
value
}
}
} as any
}
entries(): IterableIterator<[any, any]> {
const iterator = this.keys()
return {
[Symbol.iterator]: () => this.entries(),
next: () => {
const r = iterator.next()
/* istanbul ignore next */
if (r.done) return r
const value = this.get(r.value)
return {
done: false,
value: [r.value, value]
}
}
} as any
}
[Symbol.iterator]() {
return this.entries()
}
}
function proxyMap_<T extends AnyMap>(
target: T,
parent?: ImmerState
): [T, MapState] {
// @ts-ignore
const map = new DraftMap(target, parent)
return [map as any, map[DRAFT_STATE]]
}
function prepareMapCopy(state: MapState) {
if (!state.copy_) {
state.assigned_ = new Map()
state.copy_ = new Map(state.base_)
}
}
class DraftSet extends Set {
[DRAFT_STATE]: SetState
constructor(target: AnySet, parent?: ImmerState) {
super()
this[DRAFT_STATE] = {
type_: ArchType.Set,
parent_: parent,
scope_: parent ? parent.scope_ : getCurrentScope()!,
modified_: false,
finalized_: false,
copy_: undefined,
base_: target,
draft_: this,
drafts_: new Map(),
revoked_: false,
isManual_: false,
assigned_: undefined,
callbacks_: []
}
}
get size(): number {
return latest(this[DRAFT_STATE]).size
}
has(value: any): boolean {
const state: SetState = this[DRAFT_STATE]
assertUnrevoked(state)
// bit of trickery here, to be able to recognize both the value, and the draft of its value
if (!state.copy_) {
return state.base_.has(value)
}
if (state.copy_.has(value)) return true
if (state.drafts_.has(value) && state.copy_.has(state.drafts_.get(value)))
return true
return false
}
add(value: any): any {
const state: SetState = this[DRAFT_STATE]
assertUnrevoked(state)
if (!this.has(value)) {
prepareSetCopy(state)
markChanged(state)
state.copy_!.add(value)
handleCrossReference(state, value, value)
}
return this
}
delete(value: any): any {
if (!this.has(value)) {
return false
}
const state: SetState = this[DRAFT_STATE]
assertUnrevoked(state)
prepareSetCopy(state)
markChanged(state)
return (
state.copy_!.delete(value) ||
(state.drafts_.has(value)
? state.copy_!.delete(state.drafts_.get(value))
: /* istanbul ignore next */ false)
)
}
clear() {
const state: SetState = this[DRAFT_STATE]
assertUnrevoked(state)
if (latest(state).size) {
prepareSetCopy(state)
markChanged(state)
state.copy_!.clear()
}
}
values(): IterableIterator<any> {
const state: SetState = this[DRAFT_STATE]
assertUnrevoked(state)
prepareSetCopy(state)
return state.copy_!.values()
}
entries(): IterableIterator<[any, any]> {
const state: SetState = this[DRAFT_STATE]
assertUnrevoked(state)
prepareSetCopy(state)
return state.copy_!.entries()
}
keys(): IterableIterator<any> {
return this.values()
}
[Symbol.iterator]() {
return this.values()
}
forEach(cb: any, thisArg?: any) {
const iterator = this.values()
let result = iterator.next()
while (!result.done) {
cb.call(thisArg, result.value, result.value, this)
result = iterator.next()
}
}
}
function proxySet_<T extends AnySet>(
target: T,
parent?: ImmerState
): [T, SetState] {
// @ts-ignore
const set = new DraftSet(target, parent)
return [set as any, set[DRAFT_STATE]]
}
function prepareSetCopy(state: SetState) {
if (!state.copy_) {
// create drafts for all entries to preserve insertion order
state.copy_ = new Set()
state.base_.forEach(value => {
if (isDraftable(value)) {
const draft = createProxy(state.scope_, value, state, value)
state.drafts_.set(value, draft)
state.copy_!.add(draft)
} else {
state.copy_!.add(value)
}
})
}
}
function assertUnrevoked(state: any /*ES5State | MapState | SetState*/) {
if (state.revoked_) die(3, JSON.stringify(latest(state)))
}
function fixSetContents(target: ImmerState) {
// For sets we clone before iterating, otherwise we can get in endless loop due to modifying during iteration, see #628
// To preserve insertion order in all cases we then clear the set
if (target.type_ === ArchType.Set && target.copy_) {
const copy = new Set(target.copy_)
target.copy_.clear()
copy.forEach(value => {
target.copy_!.add(getValue(value))
})
}
}
loadPlugin(PluginMapSet, {proxyMap_, proxySet_, fixSetContents})
}

431
frontend/node_modules/immer/src/plugins/patches.ts generated vendored Normal file
View File

@@ -0,0 +1,431 @@
import {immerable} from "../immer"
import {
ImmerState,
Patch,
SetState,
ProxyArrayState,
MapState,
ProxyObjectState,
PatchPath,
get,
each,
has,
getArchtype,
getPrototypeOf,
isSet,
isMap,
loadPlugin,
ArchType,
die,
isDraft,
isDraftable,
NOTHING,
errors,
DRAFT_STATE,
getProxyDraft,
ImmerScope,
isObjectish,
isFunction,
CONSTRUCTOR,
PluginPatches,
isArray,
PROTOTYPE
} from "../internal"
export function enablePatches() {
const errorOffset = 16
if (process.env.NODE_ENV !== "production") {
errors.push(
'Sets cannot have "replace" patches.',
function(op: string) {
return "Unsupported patch operation: " + op
},
function(path: string) {
return "Cannot apply patch, path doesn't resolve: " + path
},
"Patching reserved attributes like __proto__, prototype and constructor is not allowed"
)
}
function getPath(state: ImmerState, path: PatchPath = []): PatchPath | null {
// Step 1: Check if state has a stored key
if (state.key_ !== undefined) {
// Step 2: Validate the key is still valid in parent
const parentCopy = state.parent_!.copy_ ?? state.parent_!.base_
const proxyDraft = getProxyDraft(get(parentCopy, state.key_!))
const valueAtKey = get(parentCopy, state.key_!)
if (valueAtKey === undefined) {
return null
}
// Check if the value at the key is still related to this draft
// It should be either the draft itself, the base, or the copy
if (
valueAtKey !== state.draft_ &&
valueAtKey !== state.base_ &&
valueAtKey !== state.copy_
) {
return null // Value was replaced with something else
}
if (proxyDraft != null && proxyDraft.base_ !== state.base_) {
return null // Different draft
}
// Step 3: Handle Set case specially
const isSet = state.parent_!.type_ === ArchType.Set
let key: string | number
if (isSet) {
// For Sets, find the index in the drafts_ map
const setParent = state.parent_ as SetState
key = Array.from(setParent.drafts_.keys()).indexOf(state.key_)
} else {
key = state.key_ as string | number
}
// Step 4: Validate key still exists in parent
if (!((isSet && parentCopy.size > key) || has(parentCopy, key))) {
return null // Key deleted
}
// Step 5: Add key to path
path.push(key)
}
// Step 6: Recurse to parent if exists
if (state.parent_) {
return getPath(state.parent_, path)
}
// Step 7: At root - reverse path and validate
path.reverse()
try {
// Validate path can be resolved from ROOT
resolvePath(state.copy_, path)
} catch (e) {
return null // Path invalid
}
return path
}
// NEW: Add resolvePath helper function
function resolvePath(base: any, path: PatchPath): any {
let current = base
for (let i = 0; i < path.length - 1; i++) {
const key = path[i]
current = get(current, key)
if (!isObjectish(current) || current === null) {
throw new Error(`Cannot resolve path at '${path.join("/")}'`)
}
}
return current
}
const REPLACE = "replace"
const ADD = "add"
const REMOVE = "remove"
function generatePatches_(
state: ImmerState,
basePath: PatchPath,
scope: ImmerScope
): void {
if (state.scope_.processedForPatches_.has(state)) {
return
}
state.scope_.processedForPatches_.add(state)
const {patches_, inversePatches_} = scope
switch (state.type_) {
case ArchType.Object:
case ArchType.Map:
return generatePatchesFromAssigned(
state,
basePath,
patches_!,
inversePatches_!
)
case ArchType.Array:
return generateArrayPatches(
state,
basePath,
patches_!,
inversePatches_!
)
case ArchType.Set:
return generateSetPatches(
(state as any) as SetState,
basePath,
patches_!,
inversePatches_!
)
}
}
function generateArrayPatches(
state: ProxyArrayState,
basePath: PatchPath,
patches: Patch[],
inversePatches: Patch[]
) {
let {base_, assigned_} = state
let copy_ = state.copy_!
// Reduce complexity by ensuring `base` is never longer.
if (copy_.length < base_.length) {
// @ts-ignore
;[base_, copy_] = [copy_, base_]
;[patches, inversePatches] = [inversePatches, patches]
}
const allReassigned = state.allIndicesReassigned_ === true
// Process replaced indices.
for (let i = 0; i < base_.length; i++) {
const copiedItem = copy_[i]
const baseItem = base_[i]
const isAssigned = allReassigned || assigned_?.get(i.toString())
if (isAssigned && copiedItem !== baseItem) {
const childState = copiedItem?.[DRAFT_STATE]
if (childState && childState.modified_) {
// Skip - let the child generate its own patches
continue
}
const path = basePath.concat([i])
patches.push({
op: REPLACE,
path,
// Need to maybe clone it, as it can in fact be the original value
// due to the base/copy inversion at the start of this function
value: clonePatchValueIfNeeded(copiedItem)
})
inversePatches.push({
op: REPLACE,
path,
value: clonePatchValueIfNeeded(baseItem)
})
}
}
// Process added indices.
for (let i = base_.length; i < copy_.length; i++) {
const path = basePath.concat([i])
patches.push({
op: ADD,
path,
// Need to maybe clone it, as it can in fact be the original value
// due to the base/copy inversion at the start of this function
value: clonePatchValueIfNeeded(copy_[i])
})
}
for (let i = copy_.length - 1; base_.length <= i; --i) {
const path = basePath.concat([i])
inversePatches.push({
op: REMOVE,
path
})
}
}
// This is used for both Map objects and normal objects.
function generatePatchesFromAssigned(
state: MapState | ProxyObjectState,
basePath: PatchPath,
patches: Patch[],
inversePatches: Patch[]
) {
const {base_, copy_, type_} = state
each(state.assigned_!, (key, assignedValue) => {
const origValue = get(base_, key, type_)
const value = get(copy_!, key, type_)
const op = !assignedValue ? REMOVE : has(base_, key) ? REPLACE : ADD
if (origValue === value && op === REPLACE) return
const path = basePath.concat(key as any)
patches.push(
op === REMOVE
? {op, path}
: {op, path, value: clonePatchValueIfNeeded(value)}
)
inversePatches.push(
op === ADD
? {op: REMOVE, path}
: op === REMOVE
? {op: ADD, path, value: clonePatchValueIfNeeded(origValue)}
: {op: REPLACE, path, value: clonePatchValueIfNeeded(origValue)}
)
})
}
function generateSetPatches(
state: SetState,
basePath: PatchPath,
patches: Patch[],
inversePatches: Patch[]
) {
let {base_, copy_} = state
let i = 0
base_.forEach((value: any) => {
if (!copy_!.has(value)) {
const path = basePath.concat([i])
patches.push({
op: REMOVE,
path,
value
})
inversePatches.unshift({
op: ADD,
path,
value
})
}
i++
})
i = 0
copy_!.forEach((value: any) => {
if (!base_.has(value)) {
const path = basePath.concat([i])
patches.push({
op: ADD,
path,
value
})
inversePatches.unshift({
op: REMOVE,
path,
value
})
}
i++
})
}
function generateReplacementPatches_(
baseValue: any,
replacement: any,
scope: ImmerScope
): void {
const {patches_, inversePatches_} = scope
patches_!.push({
op: REPLACE,
path: [],
value: replacement === NOTHING ? undefined : replacement
})
inversePatches_!.push({
op: REPLACE,
path: [],
value: baseValue
})
}
function applyPatches_<T>(draft: T, patches: readonly Patch[]): T {
patches.forEach(patch => {
const {path, op} = patch
let base: any = draft
for (let i = 0; i < path.length - 1; i++) {
const parentType = getArchtype(base)
let p = path[i]
if (typeof p !== "string" && typeof p !== "number") {
p = "" + p
}
// See #738, avoid prototype pollution
if (
(parentType === ArchType.Object || parentType === ArchType.Array) &&
(p === "__proto__" || p === CONSTRUCTOR)
)
die(errorOffset + 3)
if (isFunction(base) && p === PROTOTYPE) die(errorOffset + 3)
base = get(base, p)
if (!isObjectish(base)) die(errorOffset + 2, path.join("/"))
}
const type = getArchtype(base)
const value = deepClonePatchValue(patch.value) // used to clone patch to ensure original patch is not modified, see #411
const key = path[path.length - 1]
switch (op) {
case REPLACE:
switch (type) {
case ArchType.Map:
return base.set(key, value)
/* istanbul ignore next */
case ArchType.Set:
die(errorOffset)
default:
// if value is an object, then it's assigned by reference
// in the following add or remove ops, the value field inside the patch will also be modifyed
// so we use value from the cloned patch
// @ts-ignore
return (base[key] = value)
}
case ADD:
switch (type) {
case ArchType.Array:
return key === "-"
? base.push(value)
: base.splice(key as any, 0, value)
case ArchType.Map:
return base.set(key, value)
case ArchType.Set:
return base.add(value)
default:
return (base[key] = value)
}
case REMOVE:
switch (type) {
case ArchType.Array:
return base.splice(key as any, 1)
case ArchType.Map:
return base.delete(key)
case ArchType.Set:
return base.delete(patch.value)
default:
return delete base[key]
}
default:
die(errorOffset + 1, op)
}
})
return draft
}
// optimize: this is quite a performance hit, can we detect intelligently when it is needed?
// E.g. auto-draft when new objects from outside are assigned and modified?
// (See failing test when deepClone just returns obj)
function deepClonePatchValue<T>(obj: T): T
function deepClonePatchValue(obj: any) {
if (!isDraftable(obj)) return obj
if (isArray(obj)) return obj.map(deepClonePatchValue)
if (isMap(obj))
return new Map(
Array.from(obj.entries()).map(([k, v]) => [k, deepClonePatchValue(v)])
)
if (isSet(obj)) return new Set(Array.from(obj).map(deepClonePatchValue))
const cloned = Object.create(getPrototypeOf(obj))
for (const key in obj) cloned[key] = deepClonePatchValue(obj[key])
if (has(obj, immerable)) cloned[immerable] = obj[immerable]
return cloned
}
function clonePatchValueIfNeeded<T>(obj: T): T {
if (isDraft(obj)) {
return deepClonePatchValue(obj)
} else return obj
}
loadPlugin(PluginPatches, {
applyPatches_,
generatePatches_,
generateReplacementPatches_,
getPath
})
}

1
frontend/node_modules/immer/src/types/globals.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
declare const __DEV__: boolean

112
frontend/node_modules/immer/src/types/index.js.flow generated vendored Normal file
View File

@@ -0,0 +1,112 @@
// @flow
export interface Patch {
op: "replace" | "remove" | "add";
path: (string | number)[];
value?: any;
}
export type PatchListener = (patches: Patch[], inversePatches: Patch[]) => void
type Base = {...} | Array<any>
interface IProduce {
/**
* Immer takes a state, and runs a function against it.
* That function can freely mutate the state, as it will create copies-on-write.
* This means that the original state will stay unchanged, and once the function finishes, the modified state is returned.
*
* If the first argument is a function, this is interpreted as the recipe, and will create a curried function that will execute the recipe
* any time it is called with the current state.
*
* @param currentState - the state to start with
* @param recipe - function that receives a proxy of the current state as first argument and which can be freely modified
* @param initialState - if a curried function is created and this argument was given, it will be used as fallback if the curried function is called with a state of undefined
* @returns The next state: a new state, or the current state if nothing was modified
*/
<S: Base>(
currentState: S,
recipe: (draftState: S) => S | void,
patchListener?: PatchListener
): S;
// curried invocations with initial state
<S: Base, A = void, B = void, C = void>(
recipe: (draftState: S, a: A, b: B, c: C, ...extraArgs: any[]) => S | void,
initialState: S
): (currentState: S | void, a: A, b: B, c: C, ...extraArgs: any[]) => S;
// curried invocations without initial state
<S: Base, A = void, B = void, C = void>(
recipe: (draftState: S, a: A, b: B, c: C, ...extraArgs: any[]) => S | void
): (currentState: S, a: A, b: B, c: C, ...extraArgs: any[]) => S;
}
interface IProduceWithPatches {
/**
* Like `produce`, but instead of just returning the new state,
* a tuple is returned with [nextState, patches, inversePatches]
*
* Like produce, this function supports currying
*/
<S: Base>(
currentState: S,
recipe: (draftState: S) => S | void
): [S, Patch[], Patch[]];
// curried invocations with initial state
<S: Base, A = void, B = void, C = void>(
recipe: (draftState: S, a: A, b: B, c: C, ...extraArgs: any[]) => S | void,
initialState: S
): (currentState: S | void, a: A, b: B, c: C, ...extraArgs: any[]) => [S, Patch[], Patch[]];
// curried invocations without initial state
<S: Base, A = void, B = void, C = void>(
recipe: (draftState: S, a: A, b: B, c: C, ...extraArgs: any[]) => S | void
): (currentState: S, a: A, b: B, c: C, ...extraArgs: any[]) => [S, Patch[], Patch[]];
}
declare export var produce: IProduce
declare export var produceWithPatches: IProduceWithPatches
declare export var nothing: typeof undefined
declare export var immerable: Symbol
/**
* Automatically freezes any state trees generated by immer.
* This protects against accidental modifications of the state tree outside of an immer function.
* This comes with a performance impact, so it is recommended to disable this option in production.
* By default it is turned on during local development, and turned off in production.
*/
declare export function setAutoFreeze(autoFreeze: boolean): void
/**
* Pass false to disable strict shallow copy.
*
* By default, immer does not copy the object descriptors such as getter, setter and non-enumrable properties.
*/
declare export function setUseStrictShallowCopy(useStrictShallowCopy: boolean): void
declare export function applyPatches<S>(state: S, patches: Patch[]): S
declare export function original<S>(value: S): S
declare export function current<S>(value: S): S
declare export function isDraft(value: any): boolean
/**
* Creates a mutable draft from an (immutable) object / array.
* The draft can be modified until `finishDraft` is called
*/
declare export function createDraft<T>(base: T): T
/**
* Given a draft that was created using `createDraft`,
* finalizes the draft into a new immutable object.
* Optionally a patch-listener can be provided to gather the patches that are needed to construct the object.
*/
declare export function finishDraft<T>(base: T, listener?: PatchListener): T
declare export function enableMapSet(): void
declare export function enablePatches(): void
declare export function enableArrayMethods(): void
declare export function freeze<T>(obj: T, freeze?: boolean): T

251
frontend/node_modules/immer/src/types/types-external.ts generated vendored Normal file
View File

@@ -0,0 +1,251 @@
import {NOTHING} from "../internal"
type AnyFunc = (...args: any[]) => any
type PrimitiveType = number | string | boolean
/** Object types that should never be mapped */
type AtomicObject = Function | Promise<any> | Date | RegExp
/**
* If the lib "ES2015.Collection" is not included in tsconfig.json,
* types like ReadonlyArray, WeakMap etc. fall back to `any` (specified nowhere)
* or `{}` (from the node types), in both cases entering an infinite recursion in
* pattern matching type mappings
* This type can be used to cast these types to `void` in these cases.
*/
export type IfAvailable<T, Fallback = void> =
// fallback if any
true | false extends (T extends never
? true
: false)
? Fallback // fallback if empty type
: keyof T extends never
? Fallback // original type
: T
/**
* These should also never be mapped but must be tested after regular Map and
* Set
*/
type WeakReferences = IfAvailable<WeakMap<any, any>> | IfAvailable<WeakSet<any>>
export type WritableDraft<T> = T extends any[]
? number extends T["length"]
? Draft<T[number]>[]
: WritableNonArrayDraft<T>
: WritableNonArrayDraft<T>
type WritableNonArrayDraft<T> = {
-readonly [K in keyof T]: T[K] extends infer V
? V extends object
? Draft<V>
: V
: never
}
/** Convert a readonly type into a mutable type, if possible */
export type Draft<T> = T extends PrimitiveType
? T
: T extends AtomicObject
? T
: T extends ReadonlyMap<infer K, infer V> // Map extends ReadonlyMap
? Map<Draft<K>, Draft<V>>
: T extends ReadonlySet<infer V> // Set extends ReadonlySet
? Set<Draft<V>>
: T extends WeakReferences
? T
: T extends object
? WritableDraft<T>
: T
/** Convert a mutable type into a readonly type */
export type Immutable<T> = T extends PrimitiveType
? T
: T extends AtomicObject
? T
: T extends ReadonlyMap<infer K, infer V> // Map extends ReadonlyMap
? ReadonlyMap<Immutable<K>, Immutable<V>>
: T extends ReadonlySet<infer V> // Set extends ReadonlySet
? ReadonlySet<Immutable<V>>
: T extends WeakReferences
? T
: T extends object
? {readonly [K in keyof T]: Immutable<T[K]>}
: T
export interface Patch {
op: "replace" | "remove" | "add"
path: (string | number)[]
value?: any
}
export type PatchListener = (patches: Patch[], inversePatches: Patch[]) => void
/** Converts `nothing` into `undefined` */
type FromNothing<T> = T extends typeof NOTHING ? undefined : T
/** The inferred return type of `produce` */
export type Produced<Base, Return> = Return extends void
? Base
: FromNothing<Return>
/**
* Utility types
*/
type PatchesTuple<T> = readonly [T, Patch[], Patch[]]
type ValidRecipeReturnType<State> =
| State
| void
| undefined
| (State extends undefined ? typeof NOTHING : never)
type ReturnTypeWithPatchesIfNeeded<
State,
UsePatches extends boolean
> = UsePatches extends true ? PatchesTuple<State> : State
/**
* Core Producer inference
*/
type InferRecipeFromCurried<Curried> = Curried extends (
base: infer State,
...rest: infer Args
) => any // extra assertion to make sure this is a proper curried function (state, args) => state
? ReturnType<Curried> extends State
? (
draft: Draft<State>,
...rest: Args
) => ValidRecipeReturnType<Draft<State>>
: never
: never
type InferInitialStateFromCurried<Curried> = Curried extends (
base: infer State,
...rest: any[]
) => any // extra assertion to make sure this is a proper curried function (state, args) => state
? State
: never
type InferCurriedFromRecipe<
Recipe,
UsePatches extends boolean
> = Recipe extends (draft: infer DraftState, ...args: infer RestArgs) => any // verify return type
? ReturnType<Recipe> extends ValidRecipeReturnType<DraftState>
? (
base: Immutable<DraftState>,
...args: RestArgs
) => ReturnTypeWithPatchesIfNeeded<DraftState, UsePatches> // N.b. we return mutable draftstate, in case the recipe's first arg isn't read only, and that isn't expected as output either
: never // incorrect return type
: never // not a function
type InferCurriedFromInitialStateAndRecipe<
State,
Recipe,
UsePatches extends boolean
> = Recipe extends (
draft: Draft<State>,
...rest: infer RestArgs
) => ValidRecipeReturnType<State>
? (
base?: State | undefined,
...args: RestArgs
) => ReturnTypeWithPatchesIfNeeded<State, UsePatches>
: never // recipe doesn't match initial state
/**
* The `produce` function takes a value and a "recipe function" (whose
* return value often depends on the base state). The recipe function is
* free to mutate its first argument however it wants. All mutations are
* only ever applied to a __copy__ of the base state.
*
* Pass only a function to create a "curried producer" which relieves you
* from passing the recipe function every time.
*
* Only plain objects and arrays are made mutable. All other objects are
* considered uncopyable.
*
* Note: This function is __bound__ to its `Immer` instance.
*
* @param {any} base - the initial state
* @param {Function} producer - function that receives a proxy of the base state as first argument and which can be freely modified
* @param {Function} patchListener - optional function that will be called with all the patches produced here
* @returns {any} a new state, or the initial state if nothing was modified
*/
export interface IProduce {
/** Curried producer that infers the recipe from the curried output function (e.g. when passing to setState) */
<Curried>(
recipe: InferRecipeFromCurried<Curried>,
initialState?: InferInitialStateFromCurried<Curried>
): Curried
/** Curried producer that infers curried from the recipe */
<Recipe extends AnyFunc>(recipe: Recipe): InferCurriedFromRecipe<
Recipe,
false
>
/** Curried producer that infers curried from the State generic, which is explicitly passed in. */
<State>(
recipe: (
state: Draft<State>,
initialState: State
) => ValidRecipeReturnType<State>
): (state?: State) => State
<State, Args extends any[]>(
recipe: (
state: Draft<State>,
...args: Args
) => ValidRecipeReturnType<State>,
initialState: State
): (state?: State, ...args: Args) => State
<State>(recipe: (state: Draft<State>) => ValidRecipeReturnType<State>): (
state: State
) => State
<State, Args extends any[]>(
recipe: (state: Draft<State>, ...args: Args) => ValidRecipeReturnType<State>
): (state: State, ...args: Args) => State
/** Curried producer with initial state, infers recipe from initial state */
<State, Recipe extends Function>(
recipe: Recipe,
initialState: State
): InferCurriedFromInitialStateAndRecipe<State, Recipe, false>
/** Normal producer */
<Base, D = Draft<Base>>( // By using a default inferred D, rather than Draft<Base> in the recipe, we can override it.
base: Base,
recipe: (draft: D) => ValidRecipeReturnType<D>,
listener?: PatchListener
): Base
}
/**
* Like `produce`, but instead of just returning the new state,
* a tuple is returned with [nextState, patches, inversePatches]
*
* Like produce, this function supports currying
*/
export interface IProduceWithPatches {
// Types copied from IProduce, wrapped with PatchesTuple
<Recipe extends AnyFunc>(recipe: Recipe): InferCurriedFromRecipe<Recipe, true>
<State, Recipe extends Function>(
recipe: Recipe,
initialState: State
): InferCurriedFromInitialStateAndRecipe<State, Recipe, true>
<Base, D = Draft<Base>>(
base: Base,
recipe: (draft: D) => ValidRecipeReturnType<D>,
listener?: PatchListener
): PatchesTuple<Base>
}
/**
* The type for `recipe function`
*/
export type Producer<T> = (draft: Draft<T>) => ValidRecipeReturnType<Draft<T>>
// Fixes #507: bili doesn't export the types of this file if there is no actual source in it..
// hopefully it get's tree-shaken away for everyone :)
export function never_used() {}

View File

@@ -0,0 +1,55 @@
import {
SetState,
ImmerScope,
ProxyObjectState,
ProxyArrayState,
MapState,
DRAFT_STATE,
Patch,
PatchPath
} from "../internal"
export type Objectish = AnyObject | AnyArray | AnyMap | AnySet
export type ObjectishNoSet = AnyObject | AnyArray | AnyMap
export type AnyObject = {[key: string]: any}
export type AnyArray = Array<any>
export type AnySet = Set<any>
export type AnyMap = Map<any, any>
export const enum ArchType {
Object,
Array,
Map,
Set
}
export interface ImmerBaseState {
parent_?: ImmerState
scope_: ImmerScope
modified_: boolean
finalized_: boolean
isManual_: boolean
assigned_: Map<any, boolean> | undefined
key_?: string | number | symbol
callbacks_: ((scope: ImmerScope) => void)[]
draftLocations_?: Map<any, (string | number | symbol)[]>
}
export type ImmerState =
| ProxyObjectState
| ProxyArrayState
| MapState
| SetState
// The _internal_ type used for drafts (not to be confused with Draft, which is public facing)
export type Drafted<Base = any, T extends ImmerState = ImmerState> = {
[DRAFT_STATE]: T
} & Base
export type GeneratePatches = (
state: ImmerState,
basePath: PatchPath,
patches: Patch[],
inversePatches: Patch[]
) => void

286
frontend/node_modules/immer/src/utils/common.ts generated vendored Normal file
View File

@@ -0,0 +1,286 @@
import {
DRAFT_STATE,
DRAFTABLE,
Objectish,
Drafted,
AnyObject,
AnyMap,
AnySet,
ImmerState,
ArchType,
die,
StrictMode
} from "../internal"
const O = Object
export const getPrototypeOf = O.getPrototypeOf
export const CONSTRUCTOR = "constructor"
export const PROTOTYPE = "prototype"
export const CONFIGURABLE = "configurable"
export const ENUMERABLE = "enumerable"
export const WRITABLE = "writable"
export const VALUE = "value"
/** Returns true if the given value is an Immer draft */
/*#__PURE__*/
export let isDraft = (value: any): boolean => !!value && !!value[DRAFT_STATE]
/** Returns true if the given value can be drafted by Immer */
/*#__PURE__*/
export function isDraftable(value: any): boolean {
if (!value) return false
return (
isPlainObject(value) ||
isArray(value) ||
!!value[DRAFTABLE] ||
!!value[CONSTRUCTOR]?.[DRAFTABLE] ||
isMap(value) ||
isSet(value)
)
}
const objectCtorString = O[PROTOTYPE][CONSTRUCTOR].toString()
const cachedCtorStrings = new WeakMap()
/*#__PURE__*/
export function isPlainObject(value: any): boolean {
if (!value || !isObjectish(value)) return false
const proto = getPrototypeOf(value)
if (proto === null || proto === O[PROTOTYPE]) return true
const Ctor = O.hasOwnProperty.call(proto, CONSTRUCTOR) && proto[CONSTRUCTOR]
if (Ctor === Object) return true
if (!isFunction(Ctor)) return false
let ctorString = cachedCtorStrings.get(Ctor)
if (ctorString === undefined) {
ctorString = Function.toString.call(Ctor)
cachedCtorStrings.set(Ctor, ctorString)
}
return ctorString === objectCtorString
}
/** Get the underlying object that is represented by the given draft */
/*#__PURE__*/
export function original<T>(value: T): T | undefined
export function original(value: Drafted<any>): any {
if (!isDraft(value)) die(15, value)
return value[DRAFT_STATE].base_
}
/**
* Each iterates a map, set or array.
* Or, if any other kind of object, all of its own properties.
*
* @param obj The object to iterate over
* @param iter The iterator function
* @param strict When true (default), includes symbols and non-enumerable properties.
* When false, uses looseiteration over only enumerable string properties.
*/
export function each<T extends Objectish>(
obj: T,
iter: (key: string | number, value: any, source: T) => void,
strict?: boolean
): void
export function each(obj: any, iter: any, strict: boolean = true) {
if (getArchtype(obj) === ArchType.Object) {
// If strict, we do a full iteration including symbols and non-enumerable properties
// Otherwise, we only iterate enumerable string properties for performance
const keys = strict ? Reflect.ownKeys(obj) : O.keys(obj)
keys.forEach(key => {
iter(key, obj[key], obj)
})
} else {
obj.forEach((entry: any, index: any) => iter(index, entry, obj))
}
}
/*#__PURE__*/
export function getArchtype(thing: any): ArchType {
const state: undefined | ImmerState = thing[DRAFT_STATE]
return state
? state.type_
: isArray(thing)
? ArchType.Array
: isMap(thing)
? ArchType.Map
: isSet(thing)
? ArchType.Set
: ArchType.Object
}
/*#__PURE__*/
export let has = (
thing: any,
prop: PropertyKey,
type = getArchtype(thing)
): boolean =>
type === ArchType.Map
? thing.has(prop)
: O[PROTOTYPE].hasOwnProperty.call(thing, prop)
/*#__PURE__*/
export let get = (
thing: AnyMap | AnyObject,
prop: PropertyKey,
type = getArchtype(thing)
): any =>
// @ts-ignore
type === ArchType.Map ? thing.get(prop) : thing[prop]
/*#__PURE__*/
export let set = (
thing: any,
propOrOldValue: PropertyKey,
value: any,
type = getArchtype(thing)
) => {
if (type === ArchType.Map) thing.set(propOrOldValue, value)
else if (type === ArchType.Set) {
thing.add(value)
} else thing[propOrOldValue] = value
}
/*#__PURE__*/
export function is(x: any, y: any): boolean {
// From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js
if (x === y) {
return x !== 0 || 1 / x === 1 / y
} else {
return x !== x && y !== y
}
}
export let isArray = Array.isArray
/*#__PURE__*/
export let isMap = (target: any): target is AnyMap => target instanceof Map
/*#__PURE__*/
export let isSet = (target: any): target is AnySet => target instanceof Set
export let isObjectish = (target: any) => typeof target === "object"
export let isFunction = (target: any): target is Function =>
typeof target === "function"
export let isBoolean = (target: any): target is boolean =>
typeof target === "boolean"
export function isArrayIndex(value: string | number): value is number | string {
const n = +value
return Number.isInteger(n) && String(n) === value
}
export let getProxyDraft = <T extends any>(value: T): ImmerState | null => {
if (!isObjectish(value)) return null
return (value as {[DRAFT_STATE]: any})?.[DRAFT_STATE]
}
/*#__PURE__*/
export let latest = (state: ImmerState): any => state.copy_ || state.base_
export let getValue = <T extends object>(value: T): T => {
const proxyDraft = getProxyDraft(value)
return proxyDraft ? proxyDraft.copy_ ?? proxyDraft.base_ : value
}
export let getFinalValue = (state: ImmerState): any =>
state.modified_ ? state.copy_ : state.base_
/*#__PURE__*/
export function shallowCopy(base: any, strict: StrictMode) {
if (isMap(base)) {
return new Map(base)
}
if (isSet(base)) {
return new Set(base)
}
if (isArray(base)) return Array[PROTOTYPE].slice.call(base)
const isPlain = isPlainObject(base)
if (strict === true || (strict === "class_only" && !isPlain)) {
// Perform a strict copy
const descriptors = O.getOwnPropertyDescriptors(base)
delete descriptors[DRAFT_STATE as any]
let keys = Reflect.ownKeys(descriptors)
for (let i = 0; i < keys.length; i++) {
const key: any = keys[i]
const desc = descriptors[key]
if (desc[WRITABLE] === false) {
desc[WRITABLE] = true
desc[CONFIGURABLE] = true
}
// like object.assign, we will read any _own_, get/set accessors. This helps in dealing
// with libraries that trap values, like mobx or vue
// unlike object.assign, non-enumerables will be copied as well
if (desc.get || desc.set)
descriptors[key] = {
[CONFIGURABLE]: true,
[WRITABLE]: true, // could live with !!desc.set as well here...
[ENUMERABLE]: desc[ENUMERABLE],
[VALUE]: base[key]
}
}
return O.create(getPrototypeOf(base), descriptors)
} else {
// perform a sloppy copy
const proto = getPrototypeOf(base)
if (proto !== null && isPlain) {
return {...base} // assumption: better inner class optimization than the assign below
}
const obj = O.create(proto)
return O.assign(obj, base)
}
}
/**
* Freezes draftable objects. Returns the original object.
* By default freezes shallowly, but if the second argument is `true` it will freeze recursively.
*
* @param obj
* @param deep
*/
export function freeze<T>(obj: T, deep?: boolean): T
export function freeze<T>(obj: any, deep: boolean = false): T {
if (isFrozen(obj) || isDraft(obj) || !isDraftable(obj)) return obj
if (getArchtype(obj) > 1 /* Map or Set */) {
O.defineProperties(obj, {
set: dontMutateMethodOverride,
add: dontMutateMethodOverride,
clear: dontMutateMethodOverride,
delete: dontMutateMethodOverride
})
}
O.freeze(obj)
if (deep)
// See #590, don't recurse into non-enumerable / Symbol properties when freezing
// So use Object.values (only string-like, enumerables) instead of each()
each(
obj,
(_key, value) => {
freeze(value, true)
},
false
)
return obj
}
function dontMutateFrozenCollections() {
die(2)
}
const dontMutateMethodOverride = {
[VALUE]: dontMutateFrozenCollections
}
export function isFrozen(obj: any): boolean {
// Fast path: primitives and null/undefined are always "frozen"
if (obj === null || !isObjectish(obj)) return true
return O.isFrozen(obj)
}

18
frontend/node_modules/immer/src/utils/env.ts generated vendored Normal file
View File

@@ -0,0 +1,18 @@
// Should be no imports here!
/**
* The sentinel value returned by producers to replace the draft with undefined.
*/
export const NOTHING: unique symbol = Symbol.for("immer-nothing")
/**
* To let Immer treat your class instances as plain immutable objects
* (albeit with a custom prototype), you must define either an instance property
* or a static property on each of your custom classes.
*
* Otherwise, your class instance will never be drafted, which means it won't be
* safe to mutate in a produce callback.
*/
export const DRAFTABLE: unique symbol = Symbol.for("immer-draftable")
export const DRAFT_STATE: unique symbol = Symbol.for("immer-state")

50
frontend/node_modules/immer/src/utils/errors.ts generated vendored Normal file
View File

@@ -0,0 +1,50 @@
import {isFunction} from "../internal"
export const errors =
process.env.NODE_ENV !== "production"
? [
// All error codes, starting by 0:
function(plugin: string) {
return `The plugin for '${plugin}' has not been loaded into Immer. To enable the plugin, import and call \`enable${plugin}()\` when initializing your application.`
},
function(thing: string) {
return `produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '${thing}'`
},
"This object has been frozen and should not be mutated",
function(data: any) {
return (
"Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? " +
data
)
},
"An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.",
"Immer forbids circular references",
"The first or second argument to `produce` must be a function",
"The third argument to `produce` must be a function or undefined",
"First argument to `createDraft` must be a plain object, an array, or an immerable object",
"First argument to `finishDraft` must be a draft returned by `createDraft`",
function(thing: string) {
return `'current' expects a draft, got: ${thing}`
},
"Object.defineProperty() cannot be used on an Immer draft",
"Object.setPrototypeOf() cannot be used on an Immer draft",
"Immer only supports deleting array indices",
"Immer only supports setting array indices and the 'length' property",
function(thing: string) {
return `'original' expects a draft, got: ${thing}`
}
// Note: if more errors are added, the errorOffset in Patches.ts should be increased
// See Patches.ts for additional errors
]
: []
export function die(error: number, ...args: any[]): never {
if (process.env.NODE_ENV !== "production") {
const e = errors[error]
const msg = isFunction(e) ? e.apply(null, args as any) : e
throw new Error(`[Immer] ${msg}`)
}
throw new Error(
`[Immer] minified error nr: ${error}. Full error at: https://bit.ly/3cXEKWf`
)
}

99
frontend/node_modules/immer/src/utils/plugins.ts generated vendored Normal file
View File

@@ -0,0 +1,99 @@
import {
ImmerState,
Patch,
Drafted,
ImmerBaseState,
AnyMap,
AnySet,
ArchType,
die,
ImmerScope,
ProxyArrayState
} from "../internal"
export const PluginMapSet = "MapSet"
export const PluginPatches = "Patches"
export const PluginArrayMethods = "ArrayMethods"
export type PatchesPlugin = {
generatePatches_(
state: ImmerState,
basePath: PatchPath,
rootScope: ImmerScope
): void
generateReplacementPatches_(
base: any,
replacement: any,
rootScope: ImmerScope
): void
applyPatches_<T>(draft: T, patches: readonly Patch[]): T
getPath: (state: ImmerState) => PatchPath | null
}
export type MapSetPlugin = {
proxyMap_<T extends AnyMap>(target: T, parent?: ImmerState): [T, ImmerState]
proxySet_<T extends AnySet>(target: T, parent?: ImmerState): [T, ImmerState]
fixSetContents: (state: ImmerState) => void
}
export type ArrayMethodsPlugin = {
createMethodInterceptor: (state: ProxyArrayState, method: string) => Function
isArrayOperationMethod: (method: string) => boolean
isMutatingArrayMethod: (method: string) => boolean
}
/** Plugin utilities */
const plugins: {
Patches?: PatchesPlugin
MapSet?: MapSetPlugin
ArrayMethods?: ArrayMethodsPlugin
} = {}
type Plugins = typeof plugins
export function getPlugin<K extends keyof Plugins>(
pluginKey: K
): Exclude<Plugins[K], undefined> {
const plugin = plugins[pluginKey]
if (!plugin) {
die(0, pluginKey)
}
// @ts-ignore
return plugin
}
export let isPluginLoaded = <K extends keyof Plugins>(pluginKey: K): boolean =>
!!plugins[pluginKey]
export let clearPlugin = <K extends keyof Plugins>(pluginKey: K): void => {
delete plugins[pluginKey]
}
export function loadPlugin<K extends keyof Plugins>(
pluginKey: K,
implementation: Plugins[K]
): void {
if (!plugins[pluginKey]) plugins[pluginKey] = implementation
}
/** Map / Set plugin */
export interface MapState extends ImmerBaseState {
type_: ArchType.Map
copy_: AnyMap | undefined
base_: AnyMap
revoked_: boolean
draft_: Drafted<AnyMap, MapState>
}
export interface SetState extends ImmerBaseState {
type_: ArchType.Set
copy_: AnySet | undefined
base_: AnySet
drafts_: Map<any, Drafted> // maps the original value to the draft value in the new set
revoked_: boolean
draft_: Drafted<AnySet, SetState>
}
/** Patches plugin */
export type PatchPath = (string | number)[]