native-document 1.0.91 → 1.0.92

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.
@@ -18,7 +18,9 @@ export default function ObservableItem(value, configs = null) {
18
18
 
19
19
  this.$previousValue = null;
20
20
  this.$currentValue = value;
21
- this.$isCleanedUp = false;
21
+ if(process.env.NODE_ENV === 'development') {
22
+ this.$isCleanedUp = false;
23
+ }
22
24
 
23
25
  this.$firstListener = null;
24
26
  this.$listeners = null;
@@ -53,11 +55,12 @@ const noneTrigger = function() {};
53
55
 
54
56
  ObservableItem.prototype.intercept = function(callback) {
55
57
  this.$interceptor = callback;
58
+ this.set = this.$setWithInterceptor;
56
59
  return this;
57
60
  };
58
61
 
59
62
  ObservableItem.prototype.triggerFirstListener = function(operations) {
60
- this.$firstListener(this.$currentValue, this.$previousValue, operations || {});
63
+ this.$firstListener(this.$currentValue, this.$previousValue, operations);
61
64
  };
62
65
 
63
66
  ObservableItem.prototype.triggerListeners = function(operations) {
@@ -65,33 +68,12 @@ ObservableItem.prototype.triggerListeners = function(operations) {
65
68
  const $previousValue = this.$previousValue;
66
69
  const $currentValue = this.$currentValue;
67
70
 
68
- operations = operations || DEFAULT_OPERATIONS;
69
71
  for(let i = 0, length = $listeners.length; i < length; i++) {
70
72
  $listeners[i]($currentValue, $previousValue, operations);
71
73
  }
72
74
  };
73
75
 
74
- const handleWatcherCallback = function(callbacks, value) {
75
- if(typeof callbacks === "function") {
76
- callbacks(value);
77
- return;
78
- }
79
- if (callbacks.set) {
80
- callbacks.set(value);
81
- return;
82
- }
83
- for(let i = 0, length = callbacks.length; i < length; i++) {
84
- const callback = callbacks[i];
85
- callback.set ? callback.set(value) : callback(value);
86
-
87
- }
88
- };
89
-
90
- ObservableItem.prototype.triggerWatchers = function() {
91
- if(!this.$watchers) {
92
- return;
93
- }
94
-
76
+ ObservableItem.prototype.triggerWatchers = function(operations) {
95
77
  const $watchers = this.$watchers;
96
78
  const $previousValue = this.$previousValue;
97
79
  const $currentValue = this.$currentValue;
@@ -99,20 +81,20 @@ ObservableItem.prototype.triggerWatchers = function() {
99
81
  const $currentValueCallbacks = $watchers.get($currentValue);
100
82
  const $previousValueCallbacks = $watchers.get($previousValue);
101
83
  if($currentValueCallbacks) {
102
- handleWatcherCallback($currentValueCallbacks, true);
84
+ $currentValueCallbacks(true, $previousValue, operations);
103
85
  }
104
86
  if($previousValueCallbacks) {
105
- handleWatcherCallback($previousValueCallbacks, false);
87
+ $previousValueCallbacks(false, $currentValue, operations);
106
88
  }
107
89
  };
108
90
 
109
91
  ObservableItem.prototype.triggerAll = function(operations) {
110
- this.triggerWatchers();
92
+ this.triggerWatchers(operations);
111
93
  this.triggerListeners(operations);
112
94
  };
113
95
 
114
96
  ObservableItem.prototype.triggerWatchersAndFirstListener = function(operations) {
115
- this.triggerWatchers();
97
+ this.triggerWatchers(operations);
116
98
  this.triggerFirstListener(operations);
117
99
  };
118
100
 
@@ -140,21 +122,8 @@ ObservableItem.prototype.assocTrigger = function() {
140
122
  };
141
123
  ObservableItem.prototype.trigger = noneTrigger;
142
124
 
143
- /**
144
- * @param {*} data
145
- */
146
- ObservableItem.prototype.set = function(data) {
147
- let newValue = (typeof data === 'function') ? data(this.$currentValue) : data;
148
- newValue = Validator.isObservable(newValue) ? newValue.val() : newValue;
149
-
150
- if (this.$interceptor) {
151
- const result = this.$interceptor(newValue, this.$currentValue);
152
-
153
- if (result !== undefined) {
154
- newValue = result;
155
- }
156
- }
157
-
125
+ ObservableItem.prototype.$updateWithNewValue = function(newValue) {
126
+ newValue = newValue?.__$isObservable ? newValue.val() : newValue;
158
127
  if(this.$currentValue === newValue) {
159
128
  return;
160
129
  }
@@ -170,6 +139,30 @@ ObservableItem.prototype.set = function(data) {
170
139
  }
171
140
  };
172
141
 
142
+ /**
143
+ * @param {*} data
144
+ */
145
+ ObservableItem.prototype.$setWithInterceptor = function(data) {
146
+ let newValue = (typeof data === 'function') ? data(this.$currentValue) : data;
147
+ const result = this.$interceptor(newValue, this.$currentValue);
148
+
149
+ if (result !== undefined) {
150
+ newValue = result;
151
+ }
152
+
153
+ this.$updateWithNewValue(newValue);
154
+ }
155
+
156
+ /**
157
+ * @param {*} data
158
+ */
159
+ ObservableItem.prototype.$basicSet = function(data) {
160
+ let newValue = (typeof data === 'function') ? data(this.$currentValue) : data;
161
+ this.$updateWithNewValue(newValue);
162
+ };
163
+
164
+ ObservableItem.prototype.set = ObservableItem.prototype.$basicSet;
165
+
173
166
  ObservableItem.prototype.val = function() {
174
167
  return this.$currentValue;
175
168
  };
@@ -205,38 +198,34 @@ ObservableItem.prototype.cleanup = function() {
205
198
  }
206
199
  MemoryManager.unregister(this.$memoryId);
207
200
  this.disconnectAll();
208
- this.$isCleanedUp = true;
201
+ if(process.env.NODE_ENV === 'development') {
202
+ this.$isCleanedUp = true;
203
+ }
209
204
  delete this.$value;
210
205
  };
211
206
 
212
207
  /**
213
208
  *
214
209
  * @param {Function} callback
215
- * @param {any} target
216
210
  * @returns {(function(): void)}
217
211
  */
218
- ObservableItem.prototype.subscribe = function(callback, target = null) {
219
- this.$listeners = this.$listeners ?? [];
220
- if (this.$isCleanedUp) {
221
- DebugManager.warn('Observable subscription', '⚠️ Attempted to subscribe to a cleaned up observable.');
222
- return () => {};
223
- }
224
- if (typeof callback !== 'function') {
225
- throw new NativeDocumentError('Callback must be a function');
212
+ ObservableItem.prototype.subscribe = function(callback) {
213
+ if(process.env.NODE_ENV === 'development') {
214
+ if (this.$isCleanedUp) {
215
+ DebugManager.warn('Observable subscription', '⚠️ Attempted to subscribe to a cleaned up observable.');
216
+ return;
217
+ }
218
+ if (typeof callback !== 'function') {
219
+ throw new NativeDocumentError('Callback must be a function');
220
+ }
226
221
  }
222
+ this.$listeners = this.$listeners ?? [];
227
223
 
228
224
  this.$listeners.push(callback);
229
225
  this.assocTrigger();
230
226
  if(process.env.NODE_ENV === 'development') {
231
- PluginsManager.emit('ObservableSubscribe', this, target);
227
+ PluginsManager.emit('ObservableSubscribe', this);
232
228
  }
233
- return () => {
234
- this.unsubscribe(callback);
235
- this.assocTrigger();
236
- if(process.env.NODE_ENV === 'development') {
237
- PluginsManager.emit('ObservableUnsubscribe', this);
238
- }
239
- };
240
229
  };
241
230
 
242
231
  ObservableItem.prototype.on = function(value, callback) {
@@ -244,40 +233,66 @@ ObservableItem.prototype.on = function(value, callback) {
244
233
 
245
234
  let watchValueList = this.$watchers.get(value);
246
235
 
236
+ if(callback.__$isObservable) {
237
+ callback = callback.set.bind(callback);
238
+ }
239
+
247
240
  if(!watchValueList) {
241
+ watchValueList = callback;
248
242
  this.$watchers.set(value, callback);
249
- } else if(!Validator.isArray(watchValueList)) {
243
+ } else if(!Validator.isArray(watchValueList.list)) {
250
244
  watchValueList = [watchValueList, callback];
251
- this.$watchers.set(value, watchValueList);
245
+ callback = (value) => {
246
+ for(let i = 0, length = watchValueList.length; i < length; i++) {
247
+ watchValueList[i](value);
248
+ }
249
+ }
250
+ callback.list = watchValueList;
251
+ this.$watchers.set(value, callback);
252
252
  } else {
253
- watchValueList.push(callback);
253
+ watchValueList.list.push(callback);
254
254
  }
255
255
 
256
256
  this.assocTrigger();
257
- return () => {
258
- const index = watchValueList.indexOf(callback);
259
- watchValueList?.splice(index, 1);
260
- if(watchValueList.size === 1) {
261
- this.$watchers.set(value, watchValueList[0]);
262
- }
263
- else if(watchValueList.size === 0) {
264
- this.$watchers?.delete(value);
265
- watchValueList = null;
266
- }
257
+ };
258
+
259
+ /**
260
+ * @param {*} value
261
+ * @param {Function} callback - if omitted, removes all watchers for this value
262
+ */
263
+ ObservableItem.prototype.off = function(value, callback) {
264
+ if(!this.$watchers) return;
265
+
266
+ const watchValueList = this.$watchers.get(value);
267
+ if(!watchValueList) return;
268
+
269
+ if(!callback || !Array.isArray(watchValueList.list)) {
270
+ this.$watchers?.delete(value);
267
271
  this.assocTrigger();
268
- };
272
+ return;
273
+ }
274
+ const index = watchValueList.indexOf(callback);
275
+ watchValueList?.splice(index, 1);
276
+ if(watchValueList.length === 1) {
277
+ this.$watchers.set(value, watchValueList[0]);
278
+ }
279
+ else if(watchValueList.length === 0) {
280
+ this.$watchers?.delete(value);
281
+ watchValueList = null;
282
+ }
283
+ this.assocTrigger();
269
284
  };
270
285
 
271
286
  ObservableItem.prototype.once = function(predicate, callback) {
272
287
  const fn = typeof predicate === 'function' ? predicate : (v) => v === predicate;
273
288
 
274
- const unsub = this.subscribe((val) => {
289
+ const handler = (val) => {
275
290
  if (fn(val)) {
276
- unsub();
291
+ this.unsubscribe(handler);
277
292
  callback(val);
278
293
  }
279
- });
280
- return unsub;
294
+ };
295
+ this.subscribe(handler);
281
296
  };
282
297
 
283
298
  /**
@@ -285,11 +300,15 @@ ObservableItem.prototype.once = function(predicate, callback) {
285
300
  * @param {Function} callback
286
301
  */
287
302
  ObservableItem.prototype.unsubscribe = function(callback) {
303
+ if(!this.$listeners) return;
288
304
  const index = this.$listeners.indexOf(callback);
289
305
  if (index > -1) {
290
306
  this.$listeners.splice(index, 1);
291
307
  }
292
308
  this.assocTrigger();
309
+ if(process.env.NODE_ENV === 'development') {
310
+ PluginsManager.emit('ObservableUnsubscribe', this);
311
+ }
293
312
  };
294
313
 
295
314
  /**
@@ -340,4 +359,8 @@ ObservableItem.prototype.reset = function() {
340
359
 
341
360
  ObservableItem.prototype.toString = function() {
342
361
  return String(this.$currentValue);
362
+ };
363
+
364
+ ObservableItem.prototype.valueOf = function() {
365
+ return this.$currentValue;
343
366
  };
@@ -226,7 +226,7 @@ export function ForEachArray(data, callback, configs = {}) {
226
226
  };
227
227
 
228
228
  const buildContent = (items, _, operations) => {
229
- if(operations.action === 'clear' || !items.length) {
229
+ if(operations?.action === 'clear' || !items.length) {
230
230
  if(lastNumberOfItems === 0) {
231
231
  return;
232
232
  }