Skip to content

Commit

Permalink
update packages
Browse files Browse the repository at this point in the history
  • Loading branch information
AmauryD committed Oct 13, 2024
1 parent e52607d commit 0b48463
Show file tree
Hide file tree
Showing 10 changed files with 11,369 additions and 7,819 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ jobs:
timeout-minutes: 5

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Install Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 18.x
- uses: pnpm/action-setup@v2
node-version: 20.x
- uses: pnpm/action-setup@v3
name: Install pnpm
id: pnpm-install
with:
version: 8
version: 9
run_install: true
- name: Run Tests
run: pnpm test
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
auto-install-peers=false
136 changes: 116 additions & 20 deletions ember-immer-changeset/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@
[![Ember Observer Score](https://emberobserver.com/badges/ember-immer-changeset.svg)](https://emberobserver.com/addons/ember-immer-changeset)
[![npm version](https://badge.fury.io/js/ember-immer-changeset.svg)](https://badge.fury.io/js/ember-immer-changeset)

`ember-immer-changeset` is an Ember addon that provides a robust changeset implementation using [Immer](https://immerjs.github.io/immer/). It allows you to easily manage, apply, and rollback changes in your data with immutability guarantees.

## Key Features

- **Immutable Data**: Use Immer to manage immutable changes to data objects.
- **Track Changes**: Automatically track changes and patches made to your data.
- **Validation**: Integrate validation logic and manage errors easily.
- **Revertible**: Rollback changes or properties to previous states.
- **Events**: Hooks for listening to changes on specific properties.

## Minimum Requirements

- Ember.js v4.4 or above
Expand All @@ -12,42 +22,45 @@

## Installation

To install this addon, run:

```bash
ember install ember-immer-changeset
```

## Documentation

https://triptyk.github.io/ember-immer-changeset/
For full API documentation and examples, visit the [ember-immer-changeset documentation](https://triptyk.github.io/ember-immer-changeset/).

## Example
## Example Usage

```ts
import ImmerChangeset from 'ember-immer-changeset';

// Define your data object
const userData = {
id: 1,
name: 'John Doe',
email: '[email protected]',
age: 30,
};

// Create a new changeset instance
const userChangeset = new ImmerChangeset(userData);

// Display the initial user data
console.log('Initial User Data:', userChangeset.data);

// Make changes to the user data using the set method
// Make changes
userChangeset.set('name', 'Jane Doe');
userChangeset.set('age', 31);

// Check if there are changes
console.log('Is Dirty:', userChangeset.isDirty);
console.log('Is Dirty:', userChangeset.isDirty); // true

// Get the changes made
console.log('Changes:', userChangeset.changes);
console.log('Changes:', userChangeset.changes); // [{ key: 'name', value: 'Jane Doe' }, { key: 'age', value: 31 }]

// Validate changes
await userChangeset.validate((draftData) => {
userChangeset.removeErrors();
console.log('Validating:', draftData);
if (draftData.age < 18) {
userChangeset.addError({
originalValue: draftData.age,
Expand All @@ -57,19 +70,102 @@ await userChangeset.validate((draftData) => {
}
});

// If valid, apply and save changes
if (userChangeset.isValid) {
// Apply the changes to the original data
userChangeset.execute();
userChangeset.execute(); // Apply changes
console.log('Updated User Data:', userChangeset.data); // Updated data

userChangeset.save(); // Save changes permanently
console.log('User Data after Saving:', userChangeset.data);
}
```

// Display the updated user data
console.log('Updated User Data:', userChangeset.data);
## API Overview

// Save the changes
userChangeset.save();
### `ImmerChangeset<T>`

console.log('Is Dirty:', userChangeset.isDirty);
This class represents a changeset for a given data object. It offers the following core methods:

// Display the final user data after saving
console.log('User Data after Saving:', userChangeset.data);
}
```
- **`set(key: string, value: any)`**: Apply a change to a property.
- **`get(key: string)`**: Get the current value of a property.
- **`execute()`**: Apply all changes to the original data.
- **`rollback()`**: Revert changes back to the original state.
- **`rollbackProperty(key: string)`**: Revert a specific property.
- **`addError(error: ValidationError)`**: Add an error for a specific field.
- **`removeError(key: string)`**: Remove an error for a specific field.
- **`validate(validationFunction)`**: Validate the changeset with a custom validation function.
- **`onSet(callback)`**: Register a callback that triggers on any set operation.

### Event Hooks

You can register event listeners to trigger when changes are made:

```ts
const off = userChangeset.onSet((key, value) => {
console.log(`Property ${key} set to ${value}`);
});

// To remove the event listener
off();
```

## Additional Utilities

### `isChangeset`

This utility function checks whether a given object is an instance of `ImmerChangeset`. It is useful when you want to ensure that an object is a valid changeset before interacting with it.

```ts
import isChangeset from 'your-project/utils/isChangeset';
import ImmerChangeset from 'your-project/changeset/immer-changeset';

const userChangeset = new ImmerChangeset(userData);

// Check if the object is a changeset
console.log(isChangeset(userChangeset)); // true
```

**Function signature:**

```ts
function isChangeset(obj?: InstanceType<any>): boolean;
```

- **`obj`**: The object to check.
- **Returns**: A boolean indicating if the object is an instance of `ImmerChangeset` or has a `__changeset__` property.

---

### `changeset-get` Helper

The `changeset-get` helper is an Ember template helper that retrieves the value of a specific property from an `ImmerChangeset` instance. This is particularly helpful when you want to access changeset properties within templates.

```hbs
{{changeset-get this.userChangeset "name"}}
```

**Function signature:**

```ts
function changesetGet([changeset, key]: [ImmerChangeset | undefined, string]): any;
```

- **`changeset`**: The `ImmerChangeset` instance.
- **`key`**: The property name to retrieve from the changeset.
- **Returns**: The value of the specified property.

Usage in a template:

```hbs
{{changeset-get this.userChangeset "email"}}
```

This helper allows easy access to the values of properties on the changeset directly within Ember templates.

## Contributing

Contributions are welcome! Please see the [CONTRIBUTING.md](https://github.com/TRIPTYK/ember-immer-changeset/blob/main/CONTRIBUTING.md) for guidelines.

## License

This project is licensed under the MIT License. See the [LICENSE](https://github.com/TRIPTYK/ember-immer-changeset/blob/main/LICENSE) file for details.
3 changes: 1 addition & 2 deletions ember-immer-changeset/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
"@embroider/addon-shim": "~1.8.7",
"@glimmer/component": "~1.1.2",
"@glimmer/tracking": "~1.1.2",
"ember-cli-typescript": "~5.2.1",
"immer": "~10.0.3"
},
"devDependencies": {
Expand All @@ -55,7 +54,7 @@
"@types/ember__object": "~4.0.11",
"@types/ember__owner": "~4.0.8",
"@types/events": "^3.0.3",
"ember-source": "~5.4.0",
"ember-source": "~5.12.0",
"rollup": "^4.5.2",
"rollup-plugin-copy": "^3.4.0",
"rollup-plugin-ts": "^3.2.0",
Expand Down
10 changes: 5 additions & 5 deletions ember-immer-changeset/src/changeset/immer-changeset.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Get, Promisable } from 'type-fest';
import type { Get, Promisable, StringKeyOf } from 'type-fest';
import {
produce,
type Draft,
Expand Down Expand Up @@ -173,14 +173,14 @@ export default class ImmerChangeset<
this.draftData = produce(
this.draftData,
(d: Draft<T>) => {
set(d, key, value as never);
set(d, key as keyof Draft<T>, value as never);
},
(patches, inversePatches) => {
this.patches.push(...patches);
this.inversePatches.push(...inversePatches);
},
);
this.eventEmitter.emitOnSet(key as never, value);
this.eventEmitter.emitOnSet(key as StringKeyOf<T>, value as never);
}

/**
Expand All @@ -196,8 +196,8 @@ export default class ImmerChangeset<
* @param fn The callback function to register.
* @returns A function that can be called to unregister the callback.
*/
public onSet(fn: OnSetCallback<ImmerChangeset, T>) {
const listener = this.eventEmitter.on('set', fn as never);
public onSet(fn: OnSetCallback<this, T>) {
const listener = this.eventEmitter.on('set', fn);
return () => {
this.eventEmitter.off('set', listener);
};
Expand Down
3 changes: 2 additions & 1 deletion ember-immer-changeset/src/utils/event-emitter.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { StringKeyOf } from 'type-fest';
import type ImmerChangeset from '../changeset/immer-changeset';
import type { Changeset } from '../types/changeset';

export type OnSetCallback<
T extends ImmerChangeset,
T extends Changeset,
DTO extends Record<string, any>,
> = (key: StringKeyOf<DTO>, value: unknown, changeset: T) => void;

Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,9 @@
},
"devDependencies": {
"concurrently": "^8.2.2"
},
"volta": {
"node": "20.18.0",
"pnpm": "9.12.1"
}
}
Loading

0 comments on commit 0b48463

Please sign in to comment.