@nascentdigital/funnel-core 4.4.4 → 4.4.13

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.
@@ -105,4 +105,10 @@ export declare namespace ChangeSet {
105
105
  };
106
106
  }
107
107
  type ConstructorArgs = Omit<Data, 'errors'>;
108
+ type AddChangeArgs<TChange extends Change> = {
109
+ changes: TChange[];
110
+ change: Omit<TChange, 'attribution'>;
111
+ userId: string;
112
+ };
113
+ function addChange<TChange extends Change>({ changes, change, userId }: AddChangeArgs<TChange>): void;
108
114
  }
@@ -81,7 +81,7 @@ class ChangeSet {
81
81
  }
82
82
  addPageChange(userId, change) {
83
83
  // apply change
84
- addChange({
84
+ ChangeSet.addChange({
85
85
  changes: this._changes,
86
86
  change,
87
87
  userId
@@ -98,7 +98,7 @@ class ChangeSet {
98
98
  }
99
99
  addCollectionChange(userId, change) {
100
100
  // apply change
101
- addChange({
101
+ ChangeSet.addChange({
102
102
  changes: this._changes,
103
103
  change,
104
104
  userId
@@ -115,7 +115,7 @@ class ChangeSet {
115
115
  }
116
116
  addAssetChange(userId, change) {
117
117
  // apply change
118
- addChange({
118
+ ChangeSet.addChange({
119
119
  changes: this._changes,
120
120
  change,
121
121
  userId
@@ -162,26 +162,27 @@ exports.ChangeSet = ChangeSet;
162
162
  New.filter = filter;
163
163
  })(New = Data.New || (Data.New = {}));
164
164
  })(Data = ChangeSet.Data || (ChangeSet.Data = {}));
165
- })(ChangeSet || (exports.ChangeSet = ChangeSet = {}));
166
- function addChange({ changes, change, userId }) {
167
- // update existing page
168
- const updatedOn = Date.now();
169
- const changeIndex = changes.findIndex(({ id }) => change.id === id);
170
- if (changeIndex >= 0) {
171
- // update attribution (skip if it's the same change by the same user)
172
- const _a = changes[changeIndex], { type, attribution } = _a, existingChange = __rest(_a, ["type", "attribution"]);
173
- const lastAttribution = attribution.length > 0
174
- ? attribution[attribution.length - 1]
175
- : undefined;
176
- if ((lastAttribution === null || lastAttribution === void 0 ? void 0 : lastAttribution.userId) !== userId || change.type !== type) {
177
- attribution.push({ userId, updatedOn });
165
+ function addChange({ changes, change, userId }) {
166
+ // update existing page
167
+ const updatedOn = Date.now();
168
+ const changeIndex = changes.findIndex(({ id }) => change.id === id);
169
+ if (changeIndex >= 0) {
170
+ // update attribution (skip if it's the same change by the same user)
171
+ const _a = changes[changeIndex], { type, attribution } = _a, existingChange = __rest(_a, ["type", "attribution"]);
172
+ const lastAttribution = attribution.length > 0
173
+ ? attribution[attribution.length - 1]
174
+ : undefined;
175
+ if ((lastAttribution === null || lastAttribution === void 0 ? void 0 : lastAttribution.userId) !== userId || change.type !== type) {
176
+ attribution.push({ userId, updatedOn });
177
+ }
178
+ // update change
179
+ changes[changeIndex] = Object.assign(Object.assign(Object.assign({}, existingChange), change), { type,
180
+ attribution });
181
+ }
182
+ // or add a new one
183
+ else {
184
+ changes.push(Object.assign(Object.assign({}, change), { attribution: [{ userId, updatedOn }] }));
178
185
  }
179
- // update change
180
- changes[changeIndex] = Object.assign(Object.assign(Object.assign({}, existingChange), change), { type,
181
- attribution });
182
- }
183
- // or add a new one
184
- else {
185
- changes.push(Object.assign(Object.assign({}, change), { attribution: [{ userId, updatedOn }] }));
186
186
  }
187
- }
187
+ ChangeSet.addChange = addChange;
188
+ })(ChangeSet || (exports.ChangeSet = ChangeSet = {}));
@@ -15,7 +15,7 @@ export declare class PageModel<TPage extends Page = Page> {
15
15
  *
16
16
  * @param updates - a collection of updates to be applied to this page.
17
17
  */
18
- update(updates: ReadonlyArray<Page.Update>): void;
18
+ update(updates: ReadonlyArray<Page.Update>, skipSync?: boolean): void;
19
19
  private updateTags;
20
20
  private updateBlockCreate;
21
21
  private updateBlockDelete;
@@ -54,7 +54,7 @@ class PageModel {
54
54
  *
55
55
  * @param updates - a collection of updates to be applied to this page.
56
56
  */
57
- update(updates) {
57
+ update(updates, skipSync = false) {
58
58
  // apply updates
59
59
  updates.forEach(update => {
60
60
  switch (update.type) {
@@ -97,7 +97,9 @@ class PageModel {
97
97
  }
98
98
  });
99
99
  // finally, sync the model
100
- this.sync();
100
+ if (!skipSync) {
101
+ this.sync();
102
+ }
101
103
  }
102
104
  updateTags(update) {
103
105
  // replace slug
@@ -11,6 +11,8 @@ export declare class Field<TSchema extends Schema.Field.Type = Schema.Field.Type
11
11
  private readonly publishedValue;
12
12
  private _initialValue;
13
13
  private _value;
14
+ private _modifiedOn?;
15
+ private _savingOn?;
14
16
  private _editing;
15
17
  private _sandboxed;
16
18
  private _sandboxedValue;
@@ -48,6 +50,8 @@ export declare class Field<TSchema extends Schema.Field.Type = Schema.Field.Type
48
50
  didFocus(): void;
49
51
  validate(silent?: boolean): ReadonlyArray<FieldValidator.Error>;
50
52
  migrate(previous: Field<TSchema>): void;
53
+ onSaveStart(): void;
54
+ onSaveComplete(): void;
51
55
  reset(initialValue?: Schema.Field.Data<TSchema> | null): void;
52
56
  clone({ schema, eventBus, name, required }?: Field.CloneArgs<TSchema>): Field<TSchema>;
53
57
  private raiseEvent;
@@ -122,6 +122,7 @@ class Field {
122
122
  }
123
123
  // update value
124
124
  this._value = value;
125
+ this._modifiedOn = Date.now();
125
126
  // raise change event
126
127
  this.raiseEvent('changed');
127
128
  // raise error (if any)
@@ -134,6 +135,7 @@ class Field {
134
135
  }
135
136
  // update value
136
137
  this._value = value;
138
+ this._modifiedOn = Date.now();
137
139
  // raise error (if any)
138
140
  this.validate(true);
139
141
  }
@@ -189,6 +191,7 @@ class Field {
189
191
  }
190
192
  // rollback sandbox
191
193
  this._value = this._sandboxedValue;
194
+ this._modifiedOn = Date.now();
192
195
  this._sandboxed = false;
193
196
  // raise event
194
197
  this.raiseEvent('changed');
@@ -244,10 +247,25 @@ class Field {
244
247
  }
245
248
  migrate(previous) {
246
249
  this._value = previous.value;
250
+ this._modifiedOn = previous._modifiedOn;
247
251
  this._editing = true;
248
252
  this._sandboxed = previous._sandboxed;
249
253
  this._sandboxedValue = previous._sandboxedValue;
250
254
  }
255
+ onSaveStart() {
256
+ this._savingOn = Date.now();
257
+ }
258
+ onSaveComplete() {
259
+ // reset to initial value if not modified or if save is newer
260
+ const { _modifiedOn, _savingOn } = this;
261
+ if (_savingOn && (!_modifiedOn || _savingOn >= _modifiedOn)) {
262
+ this._initialValue = this._value;
263
+ delete this._optIn;
264
+ delete this._optOut;
265
+ }
266
+ // clear saving flag
267
+ delete this._savingOn;
268
+ }
251
269
  reset(initialValue) {
252
270
  // reset initial value if it's set
253
271
  if (initialValue !== undefined) {
@@ -8,11 +8,13 @@ export declare class FieldList {
8
8
  readonly schema: FieldList.ListSchema;
9
9
  readonly composition: FieldList.ListComposition;
10
10
  private _items;
11
+ private _modifiedOn?;
12
+ private _savingOn?;
11
13
  readonly id: string;
12
14
  readonly name: string;
13
15
  readonly required: boolean;
14
16
  private readonly eventBus;
15
- readonly initialValue: FieldList.ListValue | undefined;
17
+ private _initialValue;
16
18
  readonly publishedValue: FieldList.ListValue | undefined;
17
19
  private readonly _validator;
18
20
  private _errors;
@@ -20,6 +22,7 @@ export declare class FieldList {
20
22
  private _optOut?;
21
23
  constructor(args: FieldList.ConstructorArgs);
22
24
  get events$(): Observable<FieldList.Event>;
25
+ get initialValue(): Schema.Field.Data.ForCompositeType<FieldList.ListSchema> | undefined;
23
26
  get items(): ReadonlyArray<FieldList.Item>;
24
27
  get isNew(): boolean;
25
28
  get exists(): boolean;
@@ -45,6 +48,8 @@ export declare class FieldList {
45
48
  removeItem(itemId: string): void;
46
49
  removeField(field: Field | ObjectField): void;
47
50
  moveItem(fromIndex: number, toIndex: number): void;
51
+ onSaveStart(): void;
52
+ onSaveComplete(): void;
48
53
  reset(initialValue?: FieldList.ListValue | null): void;
49
54
  clone(): FieldList;
50
55
  private raiseEvent;
@@ -70,7 +70,7 @@ class FieldList {
70
70
  this.id = args.id;
71
71
  this.name = args.name;
72
72
  this.required = args.required;
73
- this.initialValue = args.initialValue;
73
+ this._initialValue = args.initialValue;
74
74
  this.publishedValue = args.publishedValue;
75
75
  this._validator = new FieldListValidator_1.FieldListValidator(this.schema);
76
76
  // validate
@@ -79,6 +79,9 @@ class FieldList {
79
79
  get events$() {
80
80
  return this.eventBus.events$.pipe((0, rxjs_1.filter)(FieldList.Event.filter), (0, rxjs_1.filter)(e => e.field === this));
81
81
  }
82
+ get initialValue() {
83
+ return this._initialValue;
84
+ }
82
85
  get items() {
83
86
  return this._items;
84
87
  }
@@ -127,6 +130,7 @@ class FieldList {
127
130
  value,
128
131
  publishedValue
129
132
  });
133
+ this._modifiedOn = Date.now();
130
134
  // revalidate
131
135
  this.validate();
132
136
  // raise event
@@ -221,6 +225,7 @@ class FieldList {
221
225
  };
222
226
  // add to list
223
227
  this._items = [...this._items, item];
228
+ this._modifiedOn = Date.now();
224
229
  // revalidate
225
230
  this.validate();
226
231
  // raise event
@@ -234,6 +239,8 @@ class FieldList {
234
239
  this._items = this._items.filter(({ id }) => !itemIds.includes(id));
235
240
  // raise event (if there are changes)
236
241
  if (this._items.length !== itemCount) {
242
+ // update modified
243
+ this._modifiedOn = Date.now();
237
244
  // revalidate
238
245
  this.validate();
239
246
  // raise change
@@ -268,11 +275,26 @@ class FieldList {
268
275
  items.splice(toIndex, 0, item);
269
276
  // update items
270
277
  this._items = items;
278
+ this._modifiedOn = Date.now();
271
279
  // revalidate
272
280
  this.validate();
273
281
  // raise change
274
282
  this.raiseEvent('changed');
275
283
  }
284
+ onSaveStart() {
285
+ this._savingOn = Date.now();
286
+ }
287
+ onSaveComplete() {
288
+ // reset to initial value if not modified or if save is newer
289
+ const { _modifiedOn, _savingOn } = this;
290
+ if (_savingOn && (!_modifiedOn || _savingOn >= _modifiedOn)) {
291
+ this._initialValue = this.value;
292
+ delete this._optIn;
293
+ delete this._optOut;
294
+ }
295
+ // clear saving flag
296
+ delete this._savingOn;
297
+ }
276
298
  reset(initialValue) {
277
299
  // re-bind new initial values
278
300
  if (initialValue || initialValue === null) {
@@ -287,6 +309,8 @@ class FieldList {
287
309
  else {
288
310
  this._items.forEach(({ field }) => field.reset());
289
311
  }
312
+ // mark modified
313
+ this._modifiedOn = Date.now();
290
314
  // revalidate
291
315
  this.validate();
292
316
  // raise final change
@@ -15,6 +15,8 @@ export declare class ObjectField {
15
15
  private readonly _content;
16
16
  private readonly _fields;
17
17
  private _initialValue;
18
+ private _modifiedOn?;
19
+ private _savingOn?;
18
20
  private _optIn?;
19
21
  private _optOut?;
20
22
  constructor(args: ObjectField.ConstructorArgs);
@@ -40,6 +42,8 @@ export declare class ObjectField {
40
42
  get shouldFocus(): boolean;
41
43
  didFocus(): boolean;
42
44
  getString(key: string | undefined): string | undefined;
45
+ onSaveStart(): void;
46
+ onSaveComplete(): void;
43
47
  reset(initialValue?: ObjectField.Value | null): void;
44
48
  clone(): ObjectField;
45
49
  private raiseEvent;
@@ -93,6 +93,8 @@ class ObjectField {
93
93
  field.value = values[key];
94
94
  }
95
95
  });
96
+ // mark modified
97
+ this._modifiedOn = Date.now();
96
98
  }
97
99
  get modified() {
98
100
  // modified if opted in/our
@@ -179,9 +181,25 @@ class ObjectField {
179
181
  return undefined;
180
182
  }
181
183
  }
184
+ onSaveStart() {
185
+ this._savingOn = Date.now();
186
+ }
187
+ onSaveComplete() {
188
+ // reset to initial value if not modified or if save is newer
189
+ const { _modifiedOn, _savingOn } = this;
190
+ if (_savingOn && (!_modifiedOn || _savingOn >= _modifiedOn)) {
191
+ this._initialValue = this.value;
192
+ delete this._optIn;
193
+ delete this._optOut;
194
+ }
195
+ // clear saving flag
196
+ delete this._savingOn;
197
+ }
182
198
  reset(initialValue) {
183
199
  var _a;
200
+ // reset fields using specified value
184
201
  if (initialValue !== undefined) {
202
+ // update initial value
185
203
  this._initialValue = initialValue !== null && initialValue !== void 0 ? initialValue : undefined;
186
204
  // re-bind new initial values
187
205
  const values = (_a = initialValue === null || initialValue === void 0 ? void 0 : initialValue.value) !== null && _a !== void 0 ? _a : {};
@@ -198,10 +216,12 @@ class ObjectField {
198
216
  }
199
217
  });
200
218
  }
201
- // reset each field if there's no initial value
219
+ // or reset each field if there's no initial value
202
220
  else {
203
221
  this._fields.forEach(field => field.reset());
204
222
  }
223
+ // track modified
224
+ this._modifiedOn = Date.now();
205
225
  // raise final change
206
226
  this.raiseEvent('changed');
207
227
  }
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "@nascentdigital/funnel-core",
3
- "version": "4.4.4",
3
+ "version": "4.4.13",
4
4
  "repository": {
5
- "url": "https://github.com/nascentdigital/funnel.git",
5
+ "url": "git+https://github.com/nascentdigital/funnel.git",
6
6
  "directory": "libs/core"
7
7
  },
8
+ "publishConfig": {
9
+ "registry": "https://npmjs.org"
10
+ },
8
11
  "main": "dist/index.js",
9
12
  "types": "dist/index.d.ts",
10
13
  "exports": {
@@ -60,5 +63,5 @@
60
63
  "jest-tsd": "^0.2.2",
61
64
  "ts-jest": "^29.3.2"
62
65
  },
63
- "gitHead": "debc0f359106c88e8444638236f7ed7a4f77ec5a"
66
+ "gitHead": "af6ff70daf556e824442ce09959ecff07b43c47c"
64
67
  }