@dra2020/baseclient 1.0.73 → 1.0.77

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.
@@ -1,30 +1,33 @@
1
+ export interface IDataFlow {
2
+ dfid: () => any;
3
+ }
1
4
  interface UseItem {
2
- name: string;
3
- df: DataFlow;
5
+ name?: string;
6
+ df: IDataFlow;
4
7
  id?: any;
8
+ wasstale?: boolean;
5
9
  }
6
10
  export declare class DataFlow {
7
- uniquename: number;
8
- usesList: {
9
- [name: string]: UseItem;
10
- };
11
+ usesList: UseItem[];
11
12
  constructor();
12
- ready(): boolean;
13
- id(): any;
14
- value(): any;
15
- uses(df: DataFlow, name?: string): void;
16
- find(name: string): DataFlow;
17
- findValue(name: string): any;
18
- usesReady(): boolean;
13
+ dfid(): any;
14
+ compute(): void;
15
+ uses(df: IDataFlow, name?: string): void;
19
16
  usesStale(): boolean;
17
+ wasStale(name: string): boolean;
20
18
  usesRemember(): void;
19
+ ifcompute(): void;
21
20
  }
22
- export declare class DataFlowNonNull extends DataFlow {
21
+ export declare class DataFlowCallback extends DataFlow {
23
22
  _value: any;
24
23
  _cb: () => any;
25
24
  constructor(cb: () => any);
26
- ready(): boolean;
27
- id(): any;
28
- value(): any;
25
+ dfid(): any;
26
+ }
27
+ export declare class DataFlowStamp extends DataFlow {
28
+ _stamp: number;
29
+ constructor();
30
+ dfid(): any;
31
+ stamp(): void;
29
32
  }
30
33
  export {};
@@ -2,80 +2,83 @@
2
2
  // DataFlow: mechanism for setting up a data-flow dependency graph that gets computed on demand.
3
3
  //
4
4
  // Semantics are these:
5
- // 1. The simplest "atomic" DataFlow object just has an id() and a value(). The id() is used to check for exact
6
- // equivalence when determining if any dependents need to be recomputed. id() and value() might be the same
7
- // for something that just creates a new whole object when recomputed. In other cases, id() might represent a
8
- // hash or changestamp/timestamp that is distinct from the value(). The value may or may not be "ready" as well.
9
- // If the value is not "ready", no dependents can be computed.
5
+ // 1. The simplest "atomic" DataFlow object just has an id(). The id() is used to check for exact
6
+ // equivalence when determining if any dependents need to be recomputed.
10
7
  // 2. A DataFlow object can record that it "uses" another DataFlow object. If it does, it can use a set of helper
11
- // routines to track the state of its dependents. When its dependents are all ready(), it remembers their ids
12
- // and can later test if they are stale.
8
+ // routines to track the state of its dependents. When its dependents are "stale" (have changed) the computation
9
+ // needs to be run.
13
10
  //
14
11
  //
15
12
 
13
+ export interface IDataFlow
14
+ {
15
+ dfid: () => any;
16
+ }
17
+
16
18
  interface UseItem
17
19
  {
18
- name: string,
19
- df: DataFlow,
20
+ name?: string;
21
+ df: IDataFlow,
20
22
  id?: any,
23
+ wasstale?: boolean,
21
24
  }
22
25
 
23
26
  export class DataFlow
24
27
  {
25
- uniquename: number;
26
- usesList: { [name: string]: UseItem };
28
+ usesList: UseItem[];
27
29
 
28
30
  constructor()
29
31
  {
30
- this.usesList = {};
31
- this.uniquename = 1;
32
+ this.usesList = [];
32
33
  }
33
34
 
34
35
  // override in subclass
35
- ready(): boolean { return this.usesReady() }
36
- id(): any { return null }
37
- value(): any { return null }
36
+ dfid(): any { return null }
38
37
 
39
- uses(df: DataFlow, name?: string): void
38
+ // override in subclass
39
+ compute(): void
40
40
  {
41
- if (!name) name = `_df_${this.uniquename++}`;
42
- this.usesList[name] = { name: name, df: df };
43
41
  }
44
42
 
45
- find(name: string): DataFlow
43
+ uses(df: IDataFlow, name?: string): void
46
44
  {
47
- let ui = this.usesList[name];
48
- return ui ? ui.df : undefined;
45
+ this.usesList.push({ name: name, df: df });
49
46
  }
50
47
 
51
- findValue(name: string): any
48
+ usesStale(): boolean
52
49
  {
53
- let df = this.find(name);
54
- return df ? df.value() : undefined;
50
+ let isstale = false;
51
+ this.usesList.forEach(ui => {
52
+ ui.wasstale = ui.id !== ui.df.dfid();
53
+ if (ui.wasstale) isstale = true;
54
+ });
55
+ return isstale;
55
56
  }
56
57
 
57
- usesReady(): boolean
58
+ wasStale(name: string): boolean
58
59
  {
59
- let isready = true;
60
- Object.values(this.usesList).forEach((ui: UseItem) => { if (!ui.df.ready()) isready = false });
61
- return isready;
60
+ let ui: UseItem = this.usesList.find((ui: UseItem) => ui.name === name);
61
+ return ui != null && ui.wasstale;
62
62
  }
63
63
 
64
- usesStale(): boolean
64
+ usesRemember(): void
65
65
  {
66
- let isstale = false;
67
- Object.values(this.usesList).forEach((ui: UseItem) => { if (ui.df.id !== ui.df.id()) isstale = true });
68
- return isstale;
66
+ this.usesList.forEach(ui => { ui.id = ui.df.dfid() });
69
67
  }
70
68
 
71
- usesRemember(): void
69
+ ifcompute(): void
72
70
  {
73
- Object.values(this.usesList).forEach((ui: UseItem) => { ui.df.id = ui.df.id() });
71
+ if (this.usesStale())
72
+ {
73
+ this.usesRemember();
74
+ this.compute();
75
+ }
74
76
  }
75
77
  }
76
78
 
77
- // Takes callback that, when ready, returns non-null. The return value is both the value and the id.
78
- export class DataFlowNonNull extends DataFlow
79
+ // Takes callback that, eventually, returns non-null. The return value is both the value and the id.
80
+ // Once the value returns non-null, the callback is never called again.
81
+ export class DataFlowCallback extends DataFlow
79
82
  {
80
83
  _value: any;
81
84
  _cb: () => any;
@@ -86,21 +89,21 @@ export class DataFlowNonNull extends DataFlow
86
89
  this._cb = cb;
87
90
  }
88
91
 
89
- ready(): boolean
90
- {
91
- // Allow chaining
92
- if (!this.usesReady())
93
- return false;
92
+ dfid(): any { if (!this._value) this._value = this._cb(); return this._value }
93
+ }
94
94
 
95
- // Real core semantics, with chaining on stale
96
- if (!this._value || this.usesStale())
97
- {
98
- this._value = this._cb();
99
- if (this._value) this.usesRemember();
100
- }
101
- return !!this._value;
95
+ // Simple helper that maintains a simple monotonically increasing stamp
96
+ export class DataFlowStamp extends DataFlow
97
+ {
98
+ _stamp: number;
99
+
100
+ constructor()
101
+ {
102
+ super();
103
+ this._stamp = 0;
102
104
  }
103
105
 
104
- id(): any { return this.ready(), this._value }
105
- value(): any { return this.ready(), this._value }
106
+ dfid(): any { return this._stamp }
107
+
108
+ stamp(): void { this._stamp++ }
106
109
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dra2020/baseclient",
3
- "version": "1.0.73",
3
+ "version": "1.0.77",
4
4
  "description": "Utility functions for Javascript projects.",
5
5
  "main": "dist/baseclient.js",
6
6
  "types": "./dist/all/all.d.ts",