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

refactor: use options as second parameter #5

Merged
merged 6 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ jobs:

- run: pnpm nx format:check
- run: pnpm nx affected -t lint,test --parallel=3
- run: pnpm nx run-many -t build --parallel=3 --projects=tag:publish
2 changes: 1 addition & 1 deletion .release-it.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"versionArgs": ["--workspaces false"]
},
"hooks": {
"after:bump": "pnpx auto-changelog -p"
"after:bump": ["pnpx auto-changelog -p", "pnpm nx run-many -t docs"]
},
"plugins": {
"@release-it/bumper": {
Expand Down
1 change: 1 addition & 0 deletions packages/history-utility/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,4 @@ export default function App() {
- the `history` object has changes
- `history.snapshots` is renamed to `history.nodes`
- a `HistoryNode` has the structure `{ snapshot: Snapshot<T>; createdAt: Date; updatedAt?: Date; }`
- The second parameter of `proxyWithHistory` is now an object instead of a `boolean`. `{ skipSubscribe?: boolean }`
34 changes: 26 additions & 8 deletions packages/history-utility/docs/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

- [History](modules.md#history)
- [HistoryNode](modules.md#historynode)
- [HistoryOptions](modules.md#historyoptions)

### Functions

Expand Down Expand Up @@ -35,7 +36,7 @@

#### Defined in

[packages/history-utility/src/history-utility.ts:26](https://github.com/valtiojs/valtio-history/blob/86c1430/packages/history-utility/src/history-utility.ts#L26)
[packages/history-utility/src/history-utility.ts:27](https://github.com/valtiojs/valtio-history/blob/7853d84/packages/history-utility/src/history-utility.ts#L27)

---

Expand All @@ -59,13 +60,29 @@

#### Defined in

[packages/history-utility/src/history-utility.ts:10](https://github.com/valtiojs/valtio-history/blob/86c1430/packages/history-utility/src/history-utility.ts#L10)
[packages/history-utility/src/history-utility.ts:11](https://github.com/valtiojs/valtio-history/blob/7853d84/packages/history-utility/src/history-utility.ts#L11)

---

### HistoryOptions

Ƭ **HistoryOptions**: `Object`

#### Type declaration

| Name | Type | Description |
| :--------------- | :-------- | :---------------------------------------------------------------- |
| `skipSubscribe?` | `boolean` | determines if the internal subscribe behaviour should be skipped. |

#### Defined in

[packages/history-utility/src/history-utility.ts:44](https://github.com/valtiojs/valtio-history/blob/7853d84/packages/history-utility/src/history-utility.ts#L44)

## Functions

### proxyWithHistory

▸ **proxyWithHistory**\<`V`\>(`initialValue`, `skipSubscribe?`): `Object`
▸ **proxyWithHistory**\<`V`\>(`initialValue`, `options?`): `Object`

This creates a new proxy with history support (ProxyHistoryObject).
It includes following main properties:<br>
Expand Down Expand Up @@ -97,10 +114,10 @@ Notes: <br>

#### Parameters

| Name | Type | Default value | Description |
| :-------------- | :-------- | :------------ | :---------------------------------------------------------------- |
| `initialValue` | `V` | `undefined` | any object to track |
| `skipSubscribe` | `boolean` | `false` | determines if the internal subscribe behaviour should be skipped. |
| Name | Type | Description |
| :------------- | :--------------------------------------------------------- | :--------------------------------------------- |
| `initialValue` | `V` | any value to be tracked |
| `options?` | `boolean` \| [`HistoryOptions`](modules.md#historyoptions) | use to configure the proxyWithHistory utility. |

#### Returns

Expand All @@ -121,6 +138,7 @@ proxyObject
| `remove` | (`index`: `number`) => `undefined` \| [`HistoryNode`](modules.md#historynode)\<`V`\> | The remove method is only invoked when there are more than one nodes and when a valid index is provided. If the current index is removed, An index greater than the current index will be preferred as the next value. |
| `replace` | (`index`: `number`, `value`: `INTERNAL_Snapshot`\<`V`\>) => `void` | utility to replace a value in history. The history changes will not be affected, only the value to be replaced. If a base value is needed to operate on, the `getNode` utility can be used to retrieve a cloned historyNode. <br> <br> Notes: <br> - No operations are done on the value provided to this utility. <br> - This is an advanced method, please ensure the value provided is a snapshot of the same type of the value being tracked. <br> |
| `saveHistory` | () => `void` | a function to execute saving history when changes are made to `value` |
| `shouldSaveHistory` | (`ops`: `Op`[]) => `boolean` | a function that returns true when the history should be updated |
| `subscribe` | () => () => `void` | a function to subscribe to changes made to `value` |
| `undo` | () => `void` | a function to go back in history |
| `value` | `V` | any value to be tracked (does not have to be an object) |
Expand All @@ -136,4 +154,4 @@ const state = proxyWithHistory({

#### Defined in

[packages/history-utility/src/history-utility.ts:94](https://github.com/valtiojs/valtio-history/blob/86c1430/packages/history-utility/src/history-utility.ts#L94)
[packages/history-utility/src/history-utility.ts:128](https://github.com/valtiojs/valtio-history/blob/7853d84/packages/history-utility/src/history-utility.ts#L128)
2 changes: 1 addition & 1 deletion packages/history-utility/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"options": {
"commands": [
"cd packages/history-utility && pnpm typedoc --plugin typedoc-plugin-markdown src/index.ts && rm docs/README.md",
"sleep 3s && pnpm nx format:write"
"sleep 5s && pnpm nx format:write"
]
}
}
Expand Down
7 changes: 7 additions & 0 deletions packages/history-utility/src/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const isProduction = import.meta?.env?.MODE === 'production';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work well for minification. We should simply have inline if (...).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated


export const warn = (...args: unknown[]) => {
if (!isProduction) {
console.warn(...args);
}
};
68 changes: 55 additions & 13 deletions packages/history-utility/src/history-utility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
subscribe,
} from 'valtio/vanilla';
import type { INTERNAL_Snapshot as Snapshot } from 'valtio/vanilla';
import { warn } from './helpers';

export type HistoryNode<T> = {
/**
Expand Down Expand Up @@ -38,6 +39,15 @@ export type History<T> = {
index: number;
};

type SubscribeOps = Parameters<Parameters<typeof subscribe>[1]>[0];

export type HistoryOptions = {
/**
* determines if the internal subscribe behaviour should be skipped.
*/
skipSubscribe?: boolean;
};

const isObject = (value: unknown): value is object =>
!!value && typeof value === 'object';

Expand All @@ -59,6 +69,30 @@ const deepClone = <T>(value: T): T => {
return baseObject;
};

const normalizeOptions = (
options?: HistoryOptions | boolean
): HistoryOptions => {
if (typeof options === 'boolean') {
warn(`The second parameter of 'proxyWithHistory' as boolean is deprecated and support for boolean will be removed
in the next major version. Please use the object syntax instead:

{ skipSubscribe: boolean }
`);
return { skipSubscribe: options };
}

const defaultOptions = {
skipSubscribe: false,
};

if (!options) return defaultOptions;

return {
...defaultOptions,
...options,
};
};

/**
* This creates a new proxy with history support (ProxyHistoryObject).
* It includes following main properties:<br>
Expand All @@ -81,8 +115,8 @@ const deepClone = <T>(value: T): T => {
* Notes: <br>
* - Suspense/promise is not supported. <br>
*
* @param initialValue - any object to track
* @param skipSubscribe - determines if the internal subscribe behaviour should be skipped.
* @param initialValue - any value to be tracked
* @param options - use to configure the proxyWithHistory utility.
* @returns proxyObject
*
* @example
Expand All @@ -91,7 +125,11 @@ const deepClone = <T>(value: T): T => {
* count: 1,
* })
*/
export function proxyWithHistory<V>(initialValue: V, skipSubscribe = false) {
export function proxyWithHistory<V>(
initialValue: V,
options?: HistoryOptions | boolean
) {
const utilOptions = normalizeOptions(options);
const proxyObject = proxy({
/**
* any value to be tracked (does not have to be an object)
Expand Down Expand Up @@ -191,20 +229,24 @@ export function proxyWithHistory<V>(initialValue: V, skipSubscribe = false) {
});
++proxyObject.history.index;
},
/**
* a function that returns true when the history should be updated
*
* @param ops - subscribeOps from subscribe callback
* @returns boolean
*/
shouldSaveHistory: (ops: SubscribeOps) =>
ops.every(
(op) =>
op[1][0] === 'value' &&
(op[0] !== 'set' || op[2] !== proxyObject.history.wip)
),
/**
* a function to subscribe to changes made to `value`
*/
subscribe: () =>
subscribe(proxyObject, (ops) => {
if (
ops.every(
(op) =>
op[1][0] === 'value' &&
(op[0] !== 'set' || op[2] !== proxyObject.history.wip)
)
) {
proxyObject.saveHistory();
}
if (proxyObject.shouldSaveHistory(ops)) proxyObject.saveHistory();
}),

// history rewrite utilities
Expand Down Expand Up @@ -283,7 +325,7 @@ export function proxyWithHistory<V>(initialValue: V, skipSubscribe = false) {

proxyObject.saveHistory();

if (!skipSubscribe) {
if (!utilOptions.skipSubscribe) {
proxyObject.subscribe();
}

Expand Down
2 changes: 1 addition & 1 deletion packages/history-utility/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"module": "commonjs",
"module": "ES2020",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/history-utility/tsconfig.lib.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"declaration": true,
"types": ["node"]
"types": ["node", "vite/client"]
},
"include": ["src/**/*.ts", "src/**/*.tsx"],
"exclude": [
Expand Down
1 change: 1 addition & 0 deletions packages/history-utility/tsconfig.spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"jsx": "react-jsx",
"types": [
"vitest/globals",
"vitest/importMeta",
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
"target": "es2015",
"target": "es2020",
"module": "esnext",
"lib": ["es2020", "dom"],
"skipLibCheck": true,
Expand Down