core-3nweb-client-lib 0.28.4 → 0.29.0

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.
@@ -0,0 +1,73 @@
1
+ /**
2
+ * This represents a function that will create a promise, potentially starting
3
+ * some background process, only when it is called. Such wrap of code is needed
4
+ * for scheduling, as very often any start of an action must be postponed till
5
+ * later time. Scheduler needs a not-yet-started activity, as scheduler has
6
+ * control action's start.
7
+ */
8
+ export declare type Action<T> = () => Promise<T>;
9
+ /**
10
+ * This is a container of processes, labeled by some ids. It allows to track if
11
+ * there is a process already in progress with a given id. And, it allows to
12
+ * chain process, when needed.
13
+ *
14
+ * Common use of such class is to reuse getting of some expensive resource(s).
15
+ */
16
+ export declare class NamedProcs {
17
+ private processes;
18
+ constructor();
19
+ /**
20
+ * @param id is a string key of a process
21
+ * @return a promise of a process' completion, or undefined, if process with
22
+ * given id is unknown.
23
+ */
24
+ latestTaskAtThisMoment<T>(id: string): Promise<T> | undefined;
25
+ isProcessing(id: string): boolean;
26
+ /**
27
+ * This method will add a promise of an already started process.
28
+ * @param id is a string key of a process
29
+ * @param promise of an already started process
30
+ * @return a promise of a process' completion.
31
+ */
32
+ addStarted<T>(id: string, promise: Promise<T>): Promise<T>;
33
+ /**
34
+ * This method will start a given action only, if a process with a given id
35
+ * is not running.
36
+ * @param id is a string key of a process
37
+ * @param action is a function that starts some process
38
+ * @return a promise of a process' completion.
39
+ */
40
+ start<T>(id: string, action: Action<T>): Promise<T>;
41
+ /**
42
+ * This method will chain a given action to an already running process, or,
43
+ * if identified process is not running, this will start given action under
44
+ * a given id.
45
+ * @param id is a string key of a process
46
+ * @param action is a function that starts some process
47
+ * @return a promise of a process' completion.
48
+ */
49
+ startOrChain<T>(id: string, action: Action<T>): Promise<T>;
50
+ }
51
+ /**
52
+ * This is a container of process. It allows to track if a process is already
53
+ * in progress. It also allows to chain process, when needed.
54
+ *
55
+ * Common use of such class is to reuse getting of some expensive resource, or
56
+ * do ning something as an exclusive process.
57
+ */
58
+ export declare class SingleProc {
59
+ private onGoingIdle?;
60
+ private actions;
61
+ private running;
62
+ constructor(onGoingIdle?: (() => void) | undefined);
63
+ isProcessing(): boolean;
64
+ latestTaskAtThisMoment<T>(): Promise<T> | undefined;
65
+ addStarted<T>(promise: Promise<T>): Promise<T>;
66
+ start<T>(action: Action<T>): Promise<T>;
67
+ private runIfIdle;
68
+ startOrChain<T>(action: Action<T>): Promise<T>;
69
+ }
70
+ /**
71
+ * This wraps given function/method into syncing wrap.
72
+ */
73
+ export declare function makeSyncedFunc<T extends Function>(syncProc: SingleProc, thisArg: any, func: T): T;
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (C) 2015, 2017, 2019 - 2021 3NSoft Inc.
4
+
5
+ This program is free software: you can redistribute it and/or modify it under
6
+ the terms of the GNU General Public License as published by the Free Software
7
+ Foundation, either version 3 of the License, or (at your option) any later
8
+ version.
9
+
10
+ This program is distributed in the hope that it will be useful, but
11
+ WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+ See the GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License along with
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.makeSyncedFunc = exports.SingleProc = exports.NamedProcs = void 0;
20
+ const deferred_js_1 = require("./deferred.js");
21
+ /**
22
+ * This is a container of processes, labeled by some ids. It allows to track if
23
+ * there is a process already in progress with a given id. And, it allows to
24
+ * chain process, when needed.
25
+ *
26
+ * Common use of such class is to reuse getting of some expensive resource(s).
27
+ */
28
+ class NamedProcs {
29
+ constructor() {
30
+ this.processes = new Map();
31
+ Object.freeze(this);
32
+ }
33
+ /**
34
+ * @param id is a string key of a process
35
+ * @return a promise of a process' completion, or undefined, if process with
36
+ * given id is unknown.
37
+ */
38
+ latestTaskAtThisMoment(id) {
39
+ const proc = this.processes.get(id);
40
+ return (proc ? proc.latestTaskAtThisMoment() : undefined);
41
+ }
42
+ isProcessing(id) {
43
+ const proc = this.processes.get(id);
44
+ return (proc ? proc.isProcessing() : false);
45
+ }
46
+ /**
47
+ * This method will add a promise of an already started process.
48
+ * @param id is a string key of a process
49
+ * @param promise of an already started process
50
+ * @return a promise of a process' completion.
51
+ */
52
+ addStarted(id, promise) {
53
+ if (this.isProcessing(id)) {
54
+ throw new Error('Process with id "' + id + '" is already in progress.');
55
+ }
56
+ return this.startOrChain(id, () => promise);
57
+ }
58
+ /**
59
+ * This method will start a given action only, if a process with a given id
60
+ * is not running.
61
+ * @param id is a string key of a process
62
+ * @param action is a function that starts some process
63
+ * @return a promise of a process' completion.
64
+ */
65
+ start(id, action) {
66
+ if (this.isProcessing(id)) {
67
+ throw new Error('Process with id "' + id + '" is already in progress.');
68
+ }
69
+ return this.startOrChain(id, action);
70
+ }
71
+ /**
72
+ * This method will chain a given action to an already running process, or,
73
+ * if identified process is not running, this will start given action under
74
+ * a given id.
75
+ * @param id is a string key of a process
76
+ * @param action is a function that starts some process
77
+ * @return a promise of a process' completion.
78
+ */
79
+ startOrChain(id, action) {
80
+ let proc = this.processes.get(id);
81
+ if (!proc) {
82
+ proc = new SingleProc(() => this.processes.delete(id));
83
+ this.processes.set(id, proc);
84
+ }
85
+ return proc.startOrChain(action);
86
+ }
87
+ }
88
+ exports.NamedProcs = NamedProcs;
89
+ Object.freeze(NamedProcs.prototype);
90
+ Object.freeze(NamedProcs);
91
+ /**
92
+ * This is a container of process. It allows to track if a process is already
93
+ * in progress. It also allows to chain process, when needed.
94
+ *
95
+ * Common use of such class is to reuse getting of some expensive resource, or
96
+ * do ning something as an exclusive process.
97
+ */
98
+ class SingleProc {
99
+ constructor(onGoingIdle) {
100
+ this.onGoingIdle = onGoingIdle;
101
+ this.actions = [];
102
+ this.running = false;
103
+ Object.seal(this);
104
+ }
105
+ isProcessing() {
106
+ return (this.actions.length > 0);
107
+ }
108
+ latestTaskAtThisMoment() {
109
+ return ((this.actions.length === 0) ?
110
+ undefined :
111
+ this.actions[this.actions.length - 1].deferred.promise);
112
+ }
113
+ addStarted(promise) {
114
+ if (this.isProcessing()) {
115
+ throw new Error('Process is already in progress.');
116
+ }
117
+ return this.startOrChain(() => promise);
118
+ }
119
+ start(action) {
120
+ if (this.isProcessing()) {
121
+ throw new Error('Process is already in progress.');
122
+ }
123
+ return this.startOrChain(action);
124
+ }
125
+ async runIfIdle() {
126
+ if (this.running) {
127
+ return;
128
+ }
129
+ this.running = true;
130
+ while (this.actions.length > 0) {
131
+ const { action, deferred } = this.actions[0];
132
+ try {
133
+ const res = await action();
134
+ deferred.resolve(res);
135
+ }
136
+ catch (err) {
137
+ deferred.reject(err);
138
+ }
139
+ this.actions.shift();
140
+ }
141
+ this.running = false;
142
+ // paranoid check after seeing LiquidCore 0.7.10 on iOS
143
+ if (this.actions.length > 0) {
144
+ return this.runIfIdle();
145
+ }
146
+ // when listener is used, like with NamedPcos
147
+ if (this.onGoingIdle) {
148
+ this.onGoingIdle();
149
+ }
150
+ }
151
+ startOrChain(action) {
152
+ const deferred = (0, deferred_js_1.defer)();
153
+ this.actions.push({ action, deferred });
154
+ this.runIfIdle();
155
+ return deferred.promise;
156
+ }
157
+ }
158
+ exports.SingleProc = SingleProc;
159
+ Object.freeze(SingleProc.prototype);
160
+ Object.freeze(SingleProc);
161
+ /**
162
+ * This wraps given function/method into syncing wrap.
163
+ */
164
+ function makeSyncedFunc(syncProc, thisArg, func) {
165
+ return ((...args) => syncProc.startOrChain(() => func.apply(thisArg, args)));
166
+ }
167
+ exports.makeSyncedFunc = makeSyncedFunc;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "core-3nweb-client-lib",
3
- "version": "0.28.4",
3
+ "version": "0.29.0",
4
4
  "description": "3NWeb client core library, embeddable into different environments",
5
5
  "main": "build/lib-index.js",
6
6
  "types": "build/lib-index.d.ts",