Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(currying): support currying such makeCreator #14

Merged
merged 8 commits into from
Jul 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
282 changes: 257 additions & 25 deletions docs/README.md

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/interfaces/Options.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Enable autoFreeze, and return frozen state.

#### Defined in

[interface.ts:122](https://github.com/unadlib/mutative/blob/557d56b/src/interface.ts#L122)
[interface.ts:117](https://github.com/unadlib/mutative/blob/5b264a3/src/interface.ts#L117)

___

Expand All @@ -40,7 +40,7 @@ Enable patch, and return the patches and inversePatches.

#### Defined in

[interface.ts:118](https://github.com/unadlib/mutative/blob/557d56b/src/interface.ts#L118)
[interface.ts:113](https://github.com/unadlib/mutative/blob/5b264a3/src/interface.ts#L113)

___

Expand All @@ -53,7 +53,7 @@ And it can also return a shallow copy function(AutoFreeze and Patches should bot

#### Defined in

[interface.ts:127](https://github.com/unadlib/mutative/blob/557d56b/src/interface.ts#L127)
[interface.ts:122](https://github.com/unadlib/mutative/blob/5b264a3/src/interface.ts#L122)

___

Expand All @@ -65,4 +65,4 @@ In strict mode, Forbid accessing non-draftable values and forbid returning a non

#### Defined in

[interface.ts:114](https://github.com/unadlib/mutative/blob/557d56b/src/interface.ts#L114)
[interface.ts:109](https://github.com/unadlib/mutative/blob/5b264a3/src/interface.ts#L109)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"performance:array-object": "cd test/performance && NODE_ENV='production' ts-node array-object.ts",
"performance": "yarn build && yarn perf && yarn performance:basic && yarn performance:set-map && yarn performance:big-object && yarn performance:sample && yarn performance:array-object",
"build": "tsdx build --format esm,cjs,umd && cp dist/mutative.esm.js dist/mutative.esm.mjs",
"build:doc": "rimraf docs && typedoc --out docs src/index.ts --readme none",
"build:doc": "rimraf docs && typedoc --plugin typedoc-plugin-markdown --out docs src/index.ts --readme none",
"commit": "yarn git-cz",
"size": "size-limit",
"analyze": "size-limit --why",
Expand Down
165 changes: 2 additions & 163 deletions src/create.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,4 @@
import {
CreateResult,
Draft,
Options,
PatchesOptions,
Result,
} from './interface';
import { draftify } from './draftify';
import {
getProxyDraft,
isDraft,
isDraftable,
isEqual,
revokeProxy,
} from './utils';
import { current, handleReturnValue } from './current';
import { RAW_RETURN_SYMBOL } from './constant';
import { makeCreator } from './makeCreator';

/**
* `create(baseState, callback, options)` to create the next state
Expand All @@ -38,151 +22,6 @@ import { RAW_RETURN_SYMBOL } from './constant';
* expect(state.arr).toBe(baseState.arr);
* ```
*/
function create<
T extends any,
F extends boolean = false,
O extends PatchesOptions = false,
R extends void | Promise<void> | T | Promise<T> = void
>(
base: T,
mutate: (draft: Draft<T>) => R,
options?: Options<O, F>
): CreateResult<T, O, F, R>;
function create<
T extends any,
F extends boolean = false,
O extends PatchesOptions = false,
R extends void | Promise<void> = void
>(
base: T,
mutate: (draft: T) => R,
options?: Options<O, F>
): CreateResult<T, O, F, R>;
function create<
T extends any,
P extends any[] = [],
F extends boolean = false,
O extends PatchesOptions = false,
R extends void | Promise<void> = void
>(
mutate: (draft: Draft<T>, ...args: P) => R,
options?: Options<O, F>
): (base: T, ...args: P) => CreateResult<T, O, F, R>;
function create<
T extends any,
O extends PatchesOptions = false,
F extends boolean = false
>(base: T, options?: Options<O, F>): [T, () => Result<T, O, F>];
function create(arg0: any, arg1: any, arg2?: any): any {
if (typeof arg0 === 'function' && typeof arg1 !== 'function') {
return function (this: any, base: any, ...args: any[]) {
return create(
base,
(draft: any) => arg0.call(this, draft, ...args),
arg1
);
};
}
const base = arg0;
const mutate = arg1 as (...args: any[]) => any;
let options = arg2 as Options<any, any>;
if (typeof arg1 !== 'function') {
options = arg1;
}
if (
options !== undefined &&
Object.prototype.toString.call(options) !== '[object Object]'
) {
throw new Error(
`Invalid options: ${options}, 'options' should be an object.`
);
}
const state = isDraft(base) ? current(base) : base;
const mark = options?.mark;
const enablePatches = options?.enablePatches ?? false;
const strict = options?.strict ?? false;
const enableAutoFreeze = options?.enableAutoFreeze ?? false;
const _options: Options<any, any> = {
enableAutoFreeze,
mark,
strict,
enablePatches,
};
if (
!isDraftable(state, _options) &&
typeof state === 'object' &&
state !== null
) {
throw new Error(
`Invalid base state: create() only supports plain objects, arrays, Set, Map or using mark() to mark the state as immutable.`
);
}
const [draft, finalize] = draftify(state, _options);
if (typeof arg1 !== 'function') {
if (!isDraftable(state, _options)) {
throw new Error(
`Invalid base state: create() only supports plain objects, arrays, Set, Map or using mark() to mark the state as immutable.`
);
}
return [draft, finalize];
}
let result: any;
try {
result = mutate(draft);
} catch (error) {
revokeProxy(getProxyDraft(draft));
throw error;
}
const returnValue = (value: any) => {
const proxyDraft = getProxyDraft(draft)!;
if (!isDraft(value)) {
if (
value !== undefined &&
!isEqual(value, draft) &&
proxyDraft?.operated
) {
throw new Error(
`Either the value is returned as a new non-draft value, or only the draft is modified without returning any value.`
);
}
const rawReturnValue = value?.[RAW_RETURN_SYMBOL] as [any] | undefined;
if (rawReturnValue) {
const _value = rawReturnValue[0];
if (_options.strict && typeof value === 'object' && value !== null) {
handleReturnValue({
rootDraft: proxyDraft,
value,
useRawReturn: true,
});
}
return finalize([_value]);
}
if (value !== undefined) {
if (typeof value === 'object' && value !== null) {
handleReturnValue({ rootDraft: proxyDraft, value });
}
return finalize([value]);
}
}
if (value === draft || value === undefined) {
return finalize([]);
}
const returnedProxyDraft = getProxyDraft(value)!;
if (_options === returnedProxyDraft.options) {
if (returnedProxyDraft.operated) {
throw new Error(`Cannot return a modified child draft.`);
}
return finalize([current(value)]);
}
return finalize([value]);
};
if (result instanceof Promise) {
return result.then(returnValue, (error) => {
revokeProxy(getProxyDraft(draft)!);
throw error;
});
}
return returnValue(result);
}
const create = makeCreator();

export { create };
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { makeCreator } from './makeCreator';
export { create } from './create';
export { apply } from './apply';
export { original } from './original';
Expand Down
Loading