j-templates 6.1.6 → 6.1.8

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.
@@ -16,18 +16,19 @@ function processUpdates() {
16
16
  let callback;
17
17
  while ((callback = list_1.List.Pop(pendingUpdates)))
18
18
  callback();
19
- const now = Date.now();
20
19
  if (pendingUpdates.size === 0)
21
20
  updateScheduled = false;
22
- else if (now - frameStart < frameTime)
23
- queueMicrotask(processUpdates);
24
21
  else {
25
- frameStart = now;
22
+ frameStart = Date.now();
26
23
  window_1.wndw.requestAnimationFrame(processUpdates);
27
24
  }
28
25
  }
26
+ let highPriority = false;
29
27
  function scheduleUpdate(callback) {
30
- list_1.List.Add(pendingUpdates, callback);
28
+ if (highPriority)
29
+ list_1.List.Push(pendingUpdates, callback);
30
+ else
31
+ list_1.List.Add(pendingUpdates, callback);
31
32
  if (!updateScheduled) {
32
33
  const now = Date.now();
33
34
  updateScheduled = true;
@@ -39,6 +40,14 @@ function scheduleUpdate(callback) {
39
40
  }
40
41
  }
41
42
  }
43
+ function wrapPriorityUpdates(callback) {
44
+ return function (...args) {
45
+ const currentPriority = highPriority;
46
+ highPriority = true;
47
+ callback(...args);
48
+ highPriority = currentPriority;
49
+ };
50
+ }
42
51
  exports.DOMNodeConfig = {
43
52
  createNode(type, namespace) {
44
53
  return namespace ?
@@ -49,6 +58,7 @@ exports.DOMNodeConfig = {
49
58
  return window_1.wndw.document.createTextNode(value);
50
59
  },
51
60
  scheduleUpdate,
61
+ wrapPriorityUpdates,
52
62
  addListener(target, type, callback) {
53
63
  target.addEventListener(type, callback);
54
64
  },
@@ -2,6 +2,7 @@ export interface INodeConfig {
2
2
  createNode(type: any, namespace: string): any;
3
3
  createTextNode(value?: string): any;
4
4
  scheduleUpdate(callback: () => void): void;
5
+ wrapPriorityUpdates<P extends any[]>(callback: (...args: P) => void): (...args: P) => void;
5
6
  setText(target: any, text: string): void;
6
7
  getAttribute(target: any, attribute: string): string;
7
8
  setAttribute(target: any, attribute: string, value: string): void;
@@ -181,7 +181,7 @@ function CreateProxyFactory(alias) {
181
181
  function SetPropertyValue(object, prop, value) {
182
182
  object[prop] = value;
183
183
  const leafScopes = leafScopeCache.get(object);
184
- observableScope_1.ObservableScope.Update(leafScopes && leafScopes[prop] || scopeCache.get(object));
184
+ observableScope_1.ObservableScope.Update((leafScopes && leafScopes[prop]) || scopeCache.get(object));
185
185
  }
186
186
  function ObjectProxySetter(object, prop, value) {
187
187
  if (readOnly)
@@ -189,7 +189,7 @@ function CreateProxyFactory(alias) {
189
189
  if (prop === exports.IS_OBSERVABLE_NODE)
190
190
  throw `Cannot assign read-only property: ${exports.IS_OBSERVABLE_NODE}`;
191
191
  const jsonType = (0, jsonType_1.JsonType)(value);
192
- if (jsonType === 'value') {
192
+ if (jsonType === "value") {
193
193
  value !== object[prop] && SetPropertyValue(object, prop, value);
194
194
  }
195
195
  else {
@@ -42,6 +42,7 @@ export interface IObservableScope<T> extends IDestroyable {
42
42
  emitter: Emitter;
43
43
  emitters: (Emitter | null)[];
44
44
  calcFunctions: ICalcFunction<any>[] | null;
45
+ onDestroyed: Emitter | null;
45
46
  destroyed: boolean;
46
47
  watchEmitters: Emitter[] | null;
47
48
  watchEmittersSet: Set<Emitter> | null;
@@ -52,11 +53,13 @@ export declare namespace ObservableScope {
52
53
  (): T | Promise<T>;
53
54
  }): IObservableScope<T>;
54
55
  function Register(emitter: Emitter): void;
56
+ function Init<T>(scope: IObservableScope<T>): void;
55
57
  function Value<T>(scope: IObservableScope<T>): T;
56
58
  function Watching(): boolean;
57
59
  function Touch<T>(scope: IObservableScope<T>): void;
58
60
  function Watch<T>(scope: IObservableScope<T>, callback: EmitterCallback<[IObservableScope<T>]>): void;
59
61
  function Unwatch<T>(scope: IObservableScope<T>, callback: EmitterCallback<[IObservableScope<T> | ObservableScopeValue<T>]>): void;
62
+ function OnDestroyed(scope: IObservableScope<unknown>, callback: () => void): void;
60
63
  function Update(scope: IObservableScope<any>): void;
61
64
  function Destroy<T>(scope: IObservableScope<T>): void;
62
65
  }
@@ -83,6 +83,7 @@ function CalcScope(callback) {
83
83
  emitter: emitter_1.Emitter.Create(),
84
84
  emitters: [],
85
85
  calcFunctions: null,
86
+ onDestroyed: null,
86
87
  destroyed: false,
87
88
  watchEmitters: null,
88
89
  watchEmittersSet: null,
@@ -105,6 +106,12 @@ function CalcScope(callback) {
105
106
  }
106
107
  }
107
108
  ObservableScope.Register = Register;
109
+ function Init(scope) {
110
+ if (!scope)
111
+ return;
112
+ UpdateScope(scope);
113
+ }
114
+ ObservableScope.Init = Init;
108
115
  function Value(scope) {
109
116
  if (!scope)
110
117
  return undefined;
@@ -135,6 +142,11 @@ function CalcScope(callback) {
135
142
  emitter_1.Emitter.Remove(scope.emitter, callback);
136
143
  }
137
144
  ObservableScope.Unwatch = Unwatch;
145
+ function OnDestroyed(scope, callback) {
146
+ scope.onDestroyed ??= emitter_1.Emitter.Create();
147
+ emitter_1.Emitter.On(scope.onDestroyed, callback);
148
+ }
149
+ ObservableScope.OnDestroyed = OnDestroyed;
138
150
  function Update(scope) {
139
151
  OnSet(scope);
140
152
  }
@@ -224,6 +236,7 @@ function DestroyScope(scope) {
224
236
  scope.setCallback = null;
225
237
  scope.calcFunctions = null;
226
238
  scope.destroyed = true;
239
+ scope.onDestroyed !== null && emitter_1.Emitter.Emit(scope.onDestroyed);
227
240
  for (let x = 0; x < emitters.length; x++)
228
241
  emitter_1.Emitter.Remove(emitters[x], scope.setCallback);
229
242
  }
@@ -5,14 +5,14 @@ export declare enum AnimationType {
5
5
  }
6
6
  export declare class Animation implements IDestroyable {
7
7
  private type;
8
- private frameCount;
9
- private frameTimings;
10
- private update;
11
- private animationTimeouts;
12
8
  private running;
13
9
  private start;
14
10
  private end;
15
11
  private enabled;
12
+ private animationStart;
13
+ private animationDuration;
14
+ private animationUpdate;
15
+ private animationRun;
16
16
  get Running(): boolean;
17
17
  get Start(): number;
18
18
  get End(): number;
@@ -25,5 +25,4 @@ export declare class Animation implements IDestroyable {
25
25
  Enable(): void;
26
26
  Cancel(): void;
27
27
  Destroy(): void;
28
- private SetTimeout;
29
28
  }
@@ -1,18 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Animation = exports.AnimationType = void 0;
4
+ const domNodeConfig_1 = require("../DOM/domNodeConfig");
4
5
  var StepFunctions;
5
6
  (function (StepFunctions) {
6
- function* EaseIn(count) {
7
- var diff = 1 / count;
8
- for (var t = diff, x = 0; x < count; x++, t += diff)
9
- yield (1 - t) * (1 - t) * (1 - t) * 0 + 3 * (1 - t) * (1 - t) * t * 1 + 3 * (1 - t) * t * t * 1 + t * t * t * 1;
7
+ function EaseIn(start, duration) {
8
+ const elapsed = Date.now() - start;
9
+ const percent = Math.min(elapsed / duration, 1);
10
+ return ((1 - percent) * (1 - percent) * (1 - percent) * 0 +
11
+ 3 * (1 - percent) * (1 - percent) * percent * 1 +
12
+ 3 * (1 - percent) * percent * percent * 1 +
13
+ percent * percent * percent * 1);
10
14
  }
11
15
  StepFunctions.EaseIn = EaseIn;
12
- function* Linear(count) {
13
- var diff = 1 / count;
14
- for (var t = diff, x = 0; x < count; x++, t += diff)
15
- yield t;
16
+ function Linear(start, duration) {
17
+ const elapsed = Date.now() - start;
18
+ const percent = Math.min(elapsed / duration, 1);
19
+ return percent;
16
20
  }
17
21
  StepFunctions.Linear = Linear;
18
22
  })(StepFunctions || (StepFunctions = {}));
@@ -35,41 +39,46 @@ class Animation {
35
39
  return this.enabled;
36
40
  }
37
41
  constructor(type, duration, update) {
42
+ this.animationStart = 0;
43
+ this.animationRun = null;
38
44
  this.running = false;
39
45
  this.start = null;
40
46
  this.end = null;
41
47
  this.enabled = true;
42
48
  this.type = type;
43
- this.frameCount = Math.ceil((duration / 1000) * 60);
44
- this.frameTimings = [];
45
- var frameTime = duration / this.frameCount;
46
- for (var x = 0; x < this.frameCount; x++)
47
- this.frameTimings[x] = (x + 1) * frameTime;
48
- this.update = update;
49
- this.animationTimeouts = [];
49
+ this.animationDuration = duration;
50
+ this.animationUpdate = domNodeConfig_1.DOMNodeConfig.wrapPriorityUpdates(update);
50
51
  }
51
52
  Animate(start, end) {
52
53
  if (!this.enabled)
53
54
  return;
54
- var diff = end - start;
55
+ const diff = end - start;
55
56
  if (diff === 0)
56
57
  return;
57
58
  this.Cancel();
59
+ this.animationStart = Date.now();
58
60
  this.running = true;
59
61
  this.start = start;
60
62
  this.end = end;
61
- return new Promise(resolve => {
62
- var stepFunc = StepFunctions[AnimationType[this.type]];
63
- var index = 0;
64
- for (var step of stepFunc(this.frameCount)) {
65
- var value = (step * diff) + start;
66
- this.SetTimeout(index, value, index === (this.frameCount - 1) ? resolve : null);
67
- index++;
68
- }
63
+ return new Promise((resolve) => {
64
+ const stepFunc = StepFunctions[AnimationType[this.type]];
65
+ const animationRun = () => {
66
+ if (this.animationRun !== animationRun)
67
+ return;
68
+ const percent = stepFunc(this.animationStart, this.animationDuration);
69
+ const step = percent * diff;
70
+ const next = this.start + step;
71
+ this.animationUpdate(next);
72
+ if (percent < 1)
73
+ domNodeConfig_1.DOMNodeConfig.scheduleUpdate(this.animationRun);
74
+ else {
75
+ resolve();
76
+ }
77
+ };
78
+ this.animationRun = animationRun;
79
+ domNodeConfig_1.DOMNodeConfig.scheduleUpdate(this.animationRun);
69
80
  }).then(() => {
70
- this.running = false;
71
- this.start = null;
72
- this.end = null;
81
+ this.Cancel();
73
82
  });
74
83
  }
75
84
  Disable() {
@@ -80,20 +89,13 @@ class Animation {
80
89
  this.enabled = true;
81
90
  }
82
91
  Cancel() {
83
- for (var x = 0; x < this.animationTimeouts.length; x++)
84
- clearTimeout(this.animationTimeouts[x]);
85
92
  this.running = false;
86
93
  this.start = null;
87
94
  this.end = null;
95
+ this.animationRun = null;
88
96
  }
89
97
  Destroy() {
90
- this.Cancel();
91
- }
92
- SetTimeout(index, value, resolve) {
93
- this.animationTimeouts[index] = setTimeout(() => {
94
- this.update(value);
95
- resolve && resolve();
96
- }, this.frameTimings[index]);
98
+ this.Disable();
97
99
  }
98
100
  }
99
101
  exports.Animation = Animation;
@@ -1,6 +1,8 @@
1
1
  import { Component } from "../Node/component";
2
2
  import { IDestroyable } from "./utils.types";
3
3
  import { NodeRefTypes } from "../Node/nodeRef.types";
4
+ export declare function Computed<T extends Component<any, any, any>, K extends keyof T, V extends T[K]>(defaultValue: V): (target: T, propertyKey: K, descriptor: PropertyDescriptor) => PropertyDescriptor;
5
+ export declare function ComputedAsync<T extends Component<any, any, any>, K extends keyof T, V extends T[K]>(defaultValue: V): (target: T, propertyKey: K, descriptor: PropertyDescriptor) => PropertyDescriptor;
4
6
  export declare function State(): any;
5
7
  export declare function Value(): any;
6
8
  export declare function Scope(): typeof ScopeDecorator;
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Computed = Computed;
4
+ exports.ComputedAsync = ComputedAsync;
3
5
  exports.State = State;
4
6
  exports.Value = Value;
5
7
  exports.Scope = Scope;
@@ -9,6 +11,8 @@ exports.PreReqTemplate = PreReqTemplate;
9
11
  exports.PreReq = PreReq;
10
12
  const observableScope_1 = require("../Store/Tree/observableScope");
11
13
  const observableNode_1 = require("../Store/Tree/observableNode");
14
+ const Store_1 = require("../Store");
15
+ const json_1 = require("./json");
12
16
  const nodeInstanceMap = new WeakMap();
13
17
  const scopeInstanceMap = new WeakMap();
14
18
  const destroyPrototypeMap = new WeakMap();
@@ -27,6 +31,76 @@ function GetDestroyArrayForPrototype(prototype) {
27
31
  destroyPrototypeMap.set(prototype, array);
28
32
  return array;
29
33
  }
34
+ function Computed(defaultValue) {
35
+ return function (target, propertyKey, descriptor) {
36
+ return ComputedDecorator(target, propertyKey, descriptor, defaultValue);
37
+ };
38
+ }
39
+ function ComputedDecorator(target, prop, descriptor, defaultValue) {
40
+ const propertyKey = prop;
41
+ if (!(descriptor && descriptor.get))
42
+ throw "Computed decorator requires a getter";
43
+ if (descriptor && descriptor.set)
44
+ throw "Computed decorator does not support setters";
45
+ const getter = descriptor.get;
46
+ return {
47
+ configurable: false,
48
+ enumerable: true,
49
+ get: function () {
50
+ const scopeMap = GetScopeMapForInstance(this);
51
+ if (scopeMap[propertyKey] === undefined) {
52
+ const getterScope = observableScope_1.ObservableScope.Create(async () => getter.call(this));
53
+ const syncStore = new Store_1.StoreSync();
54
+ observableScope_1.ObservableScope.Watch(getterScope, (scope) => {
55
+ const copy = (0, json_1.JsonDeepClone)(observableScope_1.ObservableScope.Value(scope));
56
+ syncStore.Write(copy, 'root');
57
+ });
58
+ observableScope_1.ObservableScope.Init(getterScope);
59
+ const propertyScope = observableScope_1.ObservableScope.Create(() => syncStore.Get('root', defaultValue));
60
+ observableScope_1.ObservableScope.OnDestroyed(propertyScope, function () {
61
+ observableScope_1.ObservableScope.Destroy(getterScope);
62
+ });
63
+ scopeMap[propertyKey] = [propertyScope, undefined];
64
+ }
65
+ return observableScope_1.ObservableScope.Value(scopeMap[propertyKey][0]);
66
+ }
67
+ };
68
+ }
69
+ function ComputedAsync(defaultValue) {
70
+ return function (target, propertyKey, descriptor) {
71
+ return ComputedAsyncDecorator(target, propertyKey, descriptor, defaultValue);
72
+ };
73
+ }
74
+ function ComputedAsyncDecorator(target, prop, descriptor, defaultValue) {
75
+ const propertyKey = prop;
76
+ if (!(descriptor && descriptor.get))
77
+ throw "Computed decorator requires a getter";
78
+ if (descriptor && descriptor.set)
79
+ throw "Computed decorator does not support setters";
80
+ const getter = descriptor.get;
81
+ return {
82
+ configurable: false,
83
+ enumerable: true,
84
+ get: function () {
85
+ const scopeMap = GetScopeMapForInstance(this);
86
+ if (scopeMap[propertyKey] === undefined) {
87
+ const getterScope = observableScope_1.ObservableScope.Create(async () => getter.call(this));
88
+ const asyncStore = new Store_1.StoreAsync();
89
+ observableScope_1.ObservableScope.Watch(getterScope, (scope) => {
90
+ asyncStore.Write(observableScope_1.ObservableScope.Value(scope), 'root');
91
+ });
92
+ observableScope_1.ObservableScope.Init(getterScope);
93
+ const propertyScope = observableScope_1.ObservableScope.Create(() => asyncStore.Get('root', defaultValue));
94
+ observableScope_1.ObservableScope.OnDestroyed(propertyScope, function () {
95
+ observableScope_1.ObservableScope.Destroy(getterScope);
96
+ asyncStore.Destroy();
97
+ });
98
+ scopeMap[propertyKey] = [propertyScope, undefined];
99
+ }
100
+ return observableScope_1.ObservableScope.Value(scopeMap[propertyKey][0]);
101
+ }
102
+ };
103
+ }
30
104
  function State() {
31
105
  return StateDecorator;
32
106
  }
package/Utils/index.d.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  export * from "./decorators";
2
2
  export * from "./animation";
3
- export * from "./animation_v2";
package/Utils/index.js CHANGED
@@ -16,4 +16,3 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./decorators"), exports);
18
18
  __exportStar(require("./animation"), exports);
19
- __exportStar(require("./animation_v2"), exports);
package/Utils/json.js CHANGED
@@ -8,12 +8,14 @@ function JsonDiffFactory() {
8
8
  const arrayProto = Object.getPrototypeOf([]);
9
9
  const strProto = Object.getPrototypeOf("");
10
10
  const numProto = Object.getPrototypeOf(0);
11
+ const boolProto = Object.getPrototypeOf(false);
11
12
  function JsonType(value) {
12
13
  if (value === null || value === undefined)
13
14
  return "value";
14
15
  switch (Object.getPrototypeOf(value)) {
15
16
  case strProto:
16
17
  case numProto:
18
+ case boolProto:
17
19
  return "value";
18
20
  case jsonProto:
19
21
  return "object";
package/Utils/list.js CHANGED
@@ -19,7 +19,7 @@ var List;
19
19
  Split(tempList, trimSize);
20
20
  }
21
21
  function ScheduleTrimTempList() {
22
- if (!trimScheduled) {
22
+ if (!trimScheduled && tempList.size > maxTempListSize) {
23
23
  trimScheduled = true;
24
24
  requestIdleCallback(TrimTempList);
25
25
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "j-templates",
3
- "version": "6.1.6",
3
+ "version": "6.1.8",
4
4
  "description": "j-templates",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/TypesInCode/jTemplates",
@@ -1,28 +0,0 @@
1
- import { IDestroyable } from "./utils.types";
2
- export declare enum AnimationTypeV2 {
3
- Linear = 0,
4
- EaseIn = 1
5
- }
6
- export declare class AnimationV2 implements IDestroyable {
7
- private type;
8
- private running;
9
- private start;
10
- private end;
11
- private enabled;
12
- private animationStart;
13
- private animationDuration;
14
- private animationUpdate;
15
- private animationRun;
16
- get Running(): boolean;
17
- get Start(): number;
18
- get End(): number;
19
- get Enabled(): boolean;
20
- constructor(type: AnimationTypeV2, duration: number, update: {
21
- (next: number): void;
22
- });
23
- Animate(start: number, end: number): Promise<void>;
24
- Disable(): void;
25
- Enable(): void;
26
- Cancel(): void;
27
- Destroy(): void;
28
- }
@@ -1,98 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AnimationV2 = exports.AnimationTypeV2 = void 0;
4
- const domNodeConfig_1 = require("../DOM/domNodeConfig");
5
- var StepFunctions;
6
- (function (StepFunctions) {
7
- function EaseIn(start, duration) {
8
- const elapsed = Date.now() - start;
9
- const percent = Math.min(elapsed / duration, 1);
10
- return (1 - percent) * (1 - percent) * (1 - percent) * 0 + 3 * (1 - percent) * (1 - percent) * percent * 1 + 3 * (1 - percent) * percent * percent * 1 + percent * percent * percent * 1;
11
- }
12
- StepFunctions.EaseIn = EaseIn;
13
- function Linear(start, duration) {
14
- const elapsed = Date.now() - start;
15
- const percent = Math.min(elapsed / duration, 1);
16
- return percent;
17
- }
18
- StepFunctions.Linear = Linear;
19
- })(StepFunctions || (StepFunctions = {}));
20
- var AnimationTypeV2;
21
- (function (AnimationTypeV2) {
22
- AnimationTypeV2[AnimationTypeV2["Linear"] = 0] = "Linear";
23
- AnimationTypeV2[AnimationTypeV2["EaseIn"] = 1] = "EaseIn";
24
- })(AnimationTypeV2 || (exports.AnimationTypeV2 = AnimationTypeV2 = {}));
25
- class AnimationV2 {
26
- get Running() {
27
- return this.running;
28
- }
29
- get Start() {
30
- return this.start;
31
- }
32
- get End() {
33
- return this.end;
34
- }
35
- get Enabled() {
36
- return this.enabled;
37
- }
38
- constructor(type, duration, update) {
39
- this.animationStart = 0;
40
- this.animationRun = null;
41
- this.running = false;
42
- this.start = null;
43
- this.end = null;
44
- this.enabled = true;
45
- this.type = type;
46
- this.animationDuration = duration;
47
- this.animationUpdate = update;
48
- }
49
- Animate(start, end) {
50
- if (!this.enabled)
51
- return;
52
- const diff = end - start;
53
- if (diff === 0)
54
- return;
55
- this.Cancel();
56
- this.animationStart = Date.now();
57
- this.running = true;
58
- this.start = start;
59
- this.end = end;
60
- return new Promise(resolve => {
61
- const stepFunc = StepFunctions[AnimationTypeV2[this.type]];
62
- const animationRun = () => {
63
- if (this.animationRun !== animationRun)
64
- return;
65
- const percent = stepFunc(this.animationStart, this.animationDuration);
66
- const step = percent * diff;
67
- const next = this.start + step;
68
- this.animationUpdate(next);
69
- if (percent < 1)
70
- domNodeConfig_1.DOMNodeConfig.scheduleUpdate(this.animationRun);
71
- else {
72
- resolve();
73
- }
74
- };
75
- this.animationRun = animationRun;
76
- domNodeConfig_1.DOMNodeConfig.scheduleUpdate(this.animationRun);
77
- }).then(() => {
78
- this.Cancel();
79
- });
80
- }
81
- Disable() {
82
- this.Cancel();
83
- this.enabled = false;
84
- }
85
- Enable() {
86
- this.enabled = true;
87
- }
88
- Cancel() {
89
- this.running = false;
90
- this.start = null;
91
- this.end = null;
92
- this.animationRun = null;
93
- }
94
- Destroy() {
95
- this.Cancel();
96
- }
97
- }
98
- exports.AnimationV2 = AnimationV2;