@jwerre/vellum 1.2.0 → 1.3.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -108,9 +108,24 @@ export declare abstract class Collection<M extends Model<T>, T extends object> {
108
108
  add(data: T | M): M;
109
109
  /**
110
110
  * Sorts the collection using the comparator if one is defined.
111
- * Called automatically when items are added to the collection.
111
+ *
112
+ * This method is called automatically when items are added to the collection via `add()` or `reset()`.
113
+ * You can also call it manually to re-sort the collection after modifying model attributes.
114
+ *
115
+ * The sorting behavior depends on the type of comparator defined:
116
+ *
117
+ * - **String attribute**: Sorts by the specified model attribute in ascending order
118
+ * - **sortBy function** (1 argument): Sorts by the return value of the function in ascending order
119
+ * - **sort function** (2 arguments): Uses a custom comparator that returns -1, 0, or 1
120
+ *
121
+ * If no comparator is defined or the comparator returns undefined, no sorting is performed.
122
+ *
123
+ * @example
124
+ * // Manual sorting after updating a model
125
+ * user.set('priority', 5);
126
+ * collection.sort();
112
127
  */
113
- private sort;
128
+ sort(): void;
114
129
  /**
115
130
  * Resets the collection with new data, replacing all existing items.
116
131
  *
@@ -70,7 +70,22 @@ export class Collection {
70
70
  }
71
71
  /**
72
72
  * Sorts the collection using the comparator if one is defined.
73
- * Called automatically when items are added to the collection.
73
+ *
74
+ * This method is called automatically when items are added to the collection via `add()` or `reset()`.
75
+ * You can also call it manually to re-sort the collection after modifying model attributes.
76
+ *
77
+ * The sorting behavior depends on the type of comparator defined:
78
+ *
79
+ * - **String attribute**: Sorts by the specified model attribute in ascending order
80
+ * - **sortBy function** (1 argument): Sorts by the return value of the function in ascending order
81
+ * - **sort function** (2 arguments): Uses a custom comparator that returns -1, 0, or 1
82
+ *
83
+ * If no comparator is defined or the comparator returns undefined, no sorting is performed.
84
+ *
85
+ * @example
86
+ * // Manual sorting after updating a model
87
+ * user.set('priority', 5);
88
+ * collection.sort();
74
89
  */
75
90
  sort() {
76
91
  if (!this.comparator) {
@@ -106,6 +106,44 @@ export declare abstract class Model<T extends object> {
106
106
  * @returns {ValidationError || undefined} An instance of ValidationError if validation failed, otherwise undefined
107
107
  */
108
108
  get validationError(): ValidationError | undefined;
109
+ /**
110
+ * Gets the hash of attributes that have changed since the last set call.
111
+ * This is a readonly accessor - the changed object cannot be modified directly.
112
+ *
113
+ * @returns {Partial<T>} An object containing all attributes that have changed
114
+ */
115
+ get changed(): Partial<T>;
116
+ /**
117
+ * Gets the hash of previous attribute values before they were changed.
118
+ * This is a readonly accessor - the previous object cannot be modified directly.
119
+ *
120
+ * @returns {Partial<T>} An object containing the previous values of changed attributes
121
+ */
122
+ get previous(): Partial<T>;
123
+ /**
124
+ * Determines if attributes have changed since the last set call.
125
+ *
126
+ * This method checks whether any attributes were modified in the most recent
127
+ * set operation. When called without arguments, it returns true if any attributes
128
+ * have changed. When called with a specific attribute key, it returns true only
129
+ * if that particular attribute was changed.
130
+ *
131
+ * @param {keyof T} [attr] - Optional attribute key to check for changes
132
+ * @returns {boolean} True if attributes have changed, false otherwise
133
+ *
134
+ * @example
135
+ * // Check if any attributes changed
136
+ * const user = new User({ name: 'John', email: 'john@example.com' });
137
+ * user.set('name', 'Jane');
138
+ * user.hasChanged(); // Returns true
139
+ *
140
+ * @example
141
+ * // Check if a specific attribute changed
142
+ * user.set('name', 'Jane');
143
+ * user.hasChanged('name'); // Returns true
144
+ * user.hasChanged('email'); // Returns false
145
+ */
146
+ hasChanged(attr?: keyof T): boolean;
109
147
  /**
110
148
  * Provides default attribute values for new model instances.
111
149
  *
@@ -52,6 +52,16 @@ export class Model {
52
52
  * This property contains the error returned by the validate method.
53
53
  */
54
54
  #validationError = $state();
55
+ /**
56
+ * Internal hash containing all attributes that have changed since the last set call.
57
+ * This property tracks which attributes have been modified and their new values.
58
+ */
59
+ #changed = {};
60
+ /**
61
+ * Internal hash containing the previous values of attributes before they were changed.
62
+ * This property stores the original values of attributes from before the last set call.
63
+ */
64
+ #previous = {};
55
65
  /**
56
66
  * The name of the attribute that serves as the unique identifier for this model instance.
57
67
  *
@@ -92,6 +102,53 @@ export class Model {
92
102
  get validationError() {
93
103
  return this.#validationError;
94
104
  }
105
+ /**
106
+ * Gets the hash of attributes that have changed since the last set call.
107
+ * This is a readonly accessor - the changed object cannot be modified directly.
108
+ *
109
+ * @returns {Partial<T>} An object containing all attributes that have changed
110
+ */
111
+ get changed() {
112
+ return this.#changed;
113
+ }
114
+ /**
115
+ * Gets the hash of previous attribute values before they were changed.
116
+ * This is a readonly accessor - the previous object cannot be modified directly.
117
+ *
118
+ * @returns {Partial<T>} An object containing the previous values of changed attributes
119
+ */
120
+ get previous() {
121
+ return this.#previous;
122
+ }
123
+ /**
124
+ * Determines if attributes have changed since the last set call.
125
+ *
126
+ * This method checks whether any attributes were modified in the most recent
127
+ * set operation. When called without arguments, it returns true if any attributes
128
+ * have changed. When called with a specific attribute key, it returns true only
129
+ * if that particular attribute was changed.
130
+ *
131
+ * @param {keyof T} [attr] - Optional attribute key to check for changes
132
+ * @returns {boolean} True if attributes have changed, false otherwise
133
+ *
134
+ * @example
135
+ * // Check if any attributes changed
136
+ * const user = new User({ name: 'John', email: 'john@example.com' });
137
+ * user.set('name', 'Jane');
138
+ * user.hasChanged(); // Returns true
139
+ *
140
+ * @example
141
+ * // Check if a specific attribute changed
142
+ * user.set('name', 'Jane');
143
+ * user.hasChanged('name'); // Returns true
144
+ * user.hasChanged('email'); // Returns false
145
+ */
146
+ hasChanged(attr) {
147
+ if (attr !== undefined) {
148
+ return attr in this.#changed;
149
+ }
150
+ return Object.keys(this.#changed).length > 0;
151
+ }
95
152
  /**
96
153
  * Provides default attribute values for new model instances.
97
154
  *
@@ -158,6 +215,14 @@ export class Model {
158
215
  if (opts?.validate && !this.#doValidation({ ...this.#attributes, ...attrs }, opts)) {
159
216
  return false;
160
217
  }
218
+ // Store previous values and record new changes
219
+ this.#previous = {};
220
+ for (const key in attrs) {
221
+ if (key in this.#attributes) {
222
+ this.#previous[key] = this.#attributes[key];
223
+ }
224
+ }
225
+ this.#changed = attrs;
161
226
  Object.assign(this.#attributes, attrs);
162
227
  return true;
163
228
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jwerre/vellum",
3
- "version": "1.2.0",
3
+ "version": "1.3.0-next.1",
4
4
  "description": "Structural state management library for Svelte 5",
5
5
  "repository": {
6
6
  "type": "git",