@voxgig/model 3.3.0 → 3.5.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.
- package/dist/lib/builder/local.js +1 -21
- package/dist/lib/builder/local.js.map +1 -1
- package/dist/lib/watch.d.ts +20 -3
- package/dist/lib/watch.js +77 -21
- package/dist/lib/watch.js.map +1 -1
- package/lib/builder/local.ts +6 -2
- package/lib/watch.ts +112 -22
- package/package.json +4 -4
|
@@ -23,7 +23,7 @@ const local_builder = async (build, ctx) => {
|
|
|
23
23
|
for (let name in builders) {
|
|
24
24
|
let builder = builders[name];
|
|
25
25
|
let action_path = path_1.default.join(root, builder.load);
|
|
26
|
-
clear(action_path)
|
|
26
|
+
// clear(action_path)
|
|
27
27
|
let action = require(action_path);
|
|
28
28
|
if (action instanceof Promise) {
|
|
29
29
|
action = await action;
|
|
@@ -73,24 +73,4 @@ const local_builder = async (build, ctx) => {
|
|
|
73
73
|
return { ok: false, why: 'bad-step', step: ctx.step, active: false };
|
|
74
74
|
};
|
|
75
75
|
exports.local_builder = local_builder;
|
|
76
|
-
// Adapted from https://github.com/sindresorhus/import-fresh - Thanks!
|
|
77
|
-
function clear(path) {
|
|
78
|
-
let filePath = require.resolve(path);
|
|
79
|
-
if (require.cache[filePath]) {
|
|
80
|
-
const children = require.cache[filePath].children.map(child => child.id);
|
|
81
|
-
// Delete module from cache
|
|
82
|
-
delete require.cache[filePath];
|
|
83
|
-
for (const id of children) {
|
|
84
|
-
clear(id);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (require.cache[filePath] && require.cache[filePath].parent) {
|
|
88
|
-
let i = require.cache[filePath].parent.children.length;
|
|
89
|
-
while (i--) {
|
|
90
|
-
if (require.cache[filePath].parent.children[i].id === filePath) {
|
|
91
|
-
require.cache[filePath].parent.children.splice(i, 1);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
76
|
//# sourceMappingURL=local.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local.js","sourceRoot":"","sources":["../../../lib/builder/local.ts"],"names":[],"mappings":";;;;;;AACA,gDAAuB;AAKvB,uCAAuC;AACvC,MAAM,aAAa,GAAY,KAAK,EAAE,KAAY,EAAE,GAAiB,EAAE,EAAE;IACvE,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAA;IACzC,IAAI,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAA;IAE3C,IAAI,IAAI,IAAI,UAAU,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAA;YAE5C,+CAA+C;YAC/C,IAAI,IAAI,GAAG,cAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;YAG/C,6BAA6B;YAC7B,IAAI,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAA;YAElC,IAAI,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAA;YAE/C,IAAI,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAA;YAExC,kCAAkC;YAClC,gBAAgB;YAChB,KAAK,IAAI,IAAI,IAAI,QAAQ,EAAE,CAAC;gBAC1B,IAAI,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;gBAC5B,IAAI,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"local.js","sourceRoot":"","sources":["../../../lib/builder/local.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/watch.d.ts
CHANGED
|
@@ -1,16 +1,33 @@
|
|
|
1
1
|
import type { Build, BuildResult } from './types';
|
|
2
2
|
import { FSWatcher } from 'chokidar';
|
|
3
|
+
type Run = {
|
|
4
|
+
canon: string;
|
|
5
|
+
path: string;
|
|
6
|
+
start: number;
|
|
7
|
+
end: number;
|
|
8
|
+
};
|
|
9
|
+
type Canon = {
|
|
10
|
+
path: string;
|
|
11
|
+
isFolder: boolean;
|
|
12
|
+
when: number;
|
|
13
|
+
};
|
|
3
14
|
declare class Watch {
|
|
4
15
|
fsw: FSWatcher;
|
|
5
16
|
spec: any;
|
|
6
17
|
last?: BuildResult;
|
|
7
18
|
last_change_time: number;
|
|
8
19
|
build: Build | undefined;
|
|
20
|
+
runq: Run[];
|
|
21
|
+
doneq: Run[];
|
|
22
|
+
canons: Canon[];
|
|
23
|
+
running: boolean;
|
|
9
24
|
constructor(spec: any);
|
|
10
|
-
|
|
11
|
-
|
|
25
|
+
drain(): Promise<void>;
|
|
26
|
+
add(path: string): Promise<void>;
|
|
27
|
+
canon(path: string): string;
|
|
28
|
+
update(br: BuildResult): Promise<void>;
|
|
12
29
|
start(): Promise<BuildResult>;
|
|
13
|
-
run(once?: boolean): Promise<BuildResult>;
|
|
30
|
+
run(once?: boolean, trigger?: string): Promise<BuildResult>;
|
|
14
31
|
stop(): Promise<void>;
|
|
15
32
|
handleErrors(br: BuildResult): void;
|
|
16
33
|
descDeps(deps: Record<string, Record<string, {
|
package/dist/lib/watch.js
CHANGED
|
@@ -16,48 +16,103 @@ class Watch {
|
|
|
16
16
|
this.spec = spec;
|
|
17
17
|
this.fsw = new chokidar_1.FSWatcher();
|
|
18
18
|
this.last_change_time = 0;
|
|
19
|
-
|
|
20
|
-
this.
|
|
19
|
+
this.runq = [];
|
|
20
|
+
this.doneq = [];
|
|
21
|
+
this.canons = [];
|
|
22
|
+
this.running = false;
|
|
23
|
+
// const run = this.run.bind(this)
|
|
24
|
+
const drain = this.drain.bind(this);
|
|
25
|
+
this.fsw.on('change', async (path) => {
|
|
21
26
|
// TODO: needs a much more robust queue that checks for dups,
|
|
22
27
|
// otherwise BuildContext state will have concurrency corruptions
|
|
23
28
|
// Avoid rebuilding when, for example, TS rewrites all files in dist
|
|
24
|
-
const dorun =
|
|
29
|
+
// const dorun = 1111 < Date.now() - this.last_change_time
|
|
25
30
|
// console.log('CHANGE', dorun, this.last_change_time, args)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
const canon = this.canon(path);
|
|
32
|
+
const running = this.runq.find((run) => run.canon === canon);
|
|
33
|
+
if (running) {
|
|
34
|
+
// console.log('RUNNING', canon, path)
|
|
35
|
+
return;
|
|
29
36
|
}
|
|
37
|
+
this.runq.push({
|
|
38
|
+
canon,
|
|
39
|
+
path,
|
|
40
|
+
start: Date.now(),
|
|
41
|
+
end: -1,
|
|
42
|
+
});
|
|
43
|
+
// console.log('RUNQ-ADD', this.runq)
|
|
44
|
+
setImmediate(drain);
|
|
30
45
|
});
|
|
31
46
|
}
|
|
32
|
-
|
|
33
|
-
if (
|
|
34
|
-
|
|
47
|
+
async drain() {
|
|
48
|
+
if (this.running) {
|
|
49
|
+
return;
|
|
35
50
|
}
|
|
36
|
-
this.
|
|
51
|
+
this.running = true;
|
|
52
|
+
let r;
|
|
53
|
+
while (r = this.runq[0]) {
|
|
54
|
+
// console.log('DRAIN')
|
|
55
|
+
let br = await this.run(false, r.canon);
|
|
56
|
+
// console.log('BR', br)
|
|
57
|
+
this.runq.shift();
|
|
58
|
+
r.end = Date.now();
|
|
59
|
+
this.doneq.push(r);
|
|
60
|
+
// console.log('DONEQ', this.doneq)
|
|
61
|
+
}
|
|
62
|
+
this.running = false;
|
|
63
|
+
}
|
|
64
|
+
async add(path) {
|
|
65
|
+
if (!node_path_1.default.isAbsolute(path)) {
|
|
66
|
+
path = node_path_1.default.join(this.spec.require, path);
|
|
67
|
+
}
|
|
68
|
+
// Ignore if aleady added
|
|
69
|
+
if (this.canons.find((c) => c.path === path)) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const fileStat = await (0, promises_1.stat)(path);
|
|
73
|
+
const canon = {
|
|
74
|
+
path: path,
|
|
75
|
+
isFolder: fileStat.isDirectory(),
|
|
76
|
+
when: Date.now()
|
|
77
|
+
};
|
|
78
|
+
this.canons.push(canon);
|
|
79
|
+
this.fsw.add(path);
|
|
80
|
+
// console.log('ADD', canon)
|
|
37
81
|
}
|
|
38
|
-
|
|
82
|
+
// If path is inside a watched folder, return folder as canonical reference.
|
|
83
|
+
canon(path) {
|
|
84
|
+
for (const canon of this.canons) {
|
|
85
|
+
if (canon.isFolder && path.startsWith(canon.path)) {
|
|
86
|
+
return canon.path;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return path;
|
|
90
|
+
}
|
|
91
|
+
async update(br) {
|
|
39
92
|
let build = br.build;
|
|
40
93
|
let files = Object.keys(build.root.deps).reduce((files, target) => {
|
|
41
94
|
files = files.concat(Object.keys(build.root.deps[target]));
|
|
42
95
|
return files;
|
|
43
96
|
}, [build.path]);
|
|
44
97
|
// TODO: remove deleted files
|
|
45
|
-
files.forEach((file) => {
|
|
98
|
+
files.forEach(async (file) => {
|
|
46
99
|
if ('string' === typeof (file) &&
|
|
47
100
|
'' !== file &&
|
|
48
101
|
build.opts.base !== file) {
|
|
49
|
-
this.
|
|
102
|
+
await this.add(file);
|
|
50
103
|
}
|
|
51
104
|
});
|
|
52
105
|
}
|
|
53
106
|
// Returns first BuildResult
|
|
54
107
|
async start() {
|
|
55
|
-
return await this.run(false);
|
|
108
|
+
return await this.run(false, '<start>');
|
|
56
109
|
}
|
|
57
|
-
async run(once) {
|
|
110
|
+
async run(once, trigger) {
|
|
111
|
+
// console.trace()
|
|
58
112
|
var _a, _b;
|
|
59
113
|
this.last_change_time = Date.now();
|
|
60
|
-
print('\n@voxgig/model', new Date(this.last_change_time));
|
|
114
|
+
print('\n@voxgig/model', this.last_change_time, new Date(this.last_change_time));
|
|
115
|
+
print('TRIGGER:', trigger, '\n');
|
|
61
116
|
// TODO: build spec should not have src!
|
|
62
117
|
let src = (await (0, promises_1.readFile)(this.spec.path)).toString();
|
|
63
118
|
this.spec.src = src;
|
|
@@ -70,7 +125,7 @@ class Watch {
|
|
|
70
125
|
print('TOP:', Object.keys((_a = br === null || br === void 0 ? void 0 : br.build) === null || _a === void 0 ? void 0 : _a.model).join(', '), '\n');
|
|
71
126
|
if (!once) {
|
|
72
127
|
// There may be new files.
|
|
73
|
-
this.update(br);
|
|
128
|
+
await this.update(br);
|
|
74
129
|
}
|
|
75
130
|
}
|
|
76
131
|
else {
|
|
@@ -86,12 +141,13 @@ class Watch {
|
|
|
86
141
|
handleErrors(br) {
|
|
87
142
|
if (br.err) {
|
|
88
143
|
for (let be of br.err) {
|
|
89
|
-
if
|
|
144
|
+
// TODO: print stack if not a model error
|
|
145
|
+
if (be.isVal && be.msg) {
|
|
90
146
|
warn(be.msg);
|
|
91
147
|
}
|
|
92
|
-
else if (be.message) {
|
|
93
|
-
|
|
94
|
-
}
|
|
148
|
+
// else if (be.message) {
|
|
149
|
+
// warn(be.message)
|
|
150
|
+
// }
|
|
95
151
|
else {
|
|
96
152
|
warn(be);
|
|
97
153
|
}
|
package/dist/lib/watch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../lib/watch.ts"],"names":[],"mappings":";AAAA,oDAAoD;;;;;;AAEpD,0DAA4B;AAK5B,mCAAmC;AACnC,uCAAoC;AAEpC,
|
|
1
|
+
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../lib/watch.ts"],"names":[],"mappings":";AAAA,oDAAoD;;;;;;AAEpD,0DAA4B;AAK5B,mCAAmC;AACnC,uCAAoC;AAEpC,0CAA4C;AAG5C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAA;AACzB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;AAgBzB,MAAM,KAAK;IAWT,YAAY,IAAS;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,GAAG,GAAG,IAAI,oBAAS,EAAE,CAAA;QAC1B,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAA;QACzB,IAAI,CAAC,IAAI,GAAG,EAAE,CAAA;QACd,IAAI,CAAC,KAAK,GAAG,EAAE,CAAA;QACf,IAAI,CAAC,MAAM,GAAG,EAAE,CAAA;QAChB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;QAEpB,kCAAkC;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAEnC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAY,EAAE,EAAE;YAC3C,6DAA6D;YAC7D,iEAAiE;YACjE,oEAAoE;YACpE,0DAA0D;YAC1D,4DAA4D;YAE5D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YAE9B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,CAAA;YACjE,IAAI,OAAO,EAAE,CAAC;gBACZ,sCAAsC;gBACtC,OAAM;YACR,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;gBACb,KAAK;gBACL,IAAI;gBACJ,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE;gBACjB,GAAG,EAAE,CAAC,CAAC;aACR,CAAC,CAAA;YAEF,qCAAqC;YACrC,YAAY,CAAC,KAAK,CAAC,CAAA;QACrB,CAAC,CAAC,CAAA;IACJ,CAAC;IAGD,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAM;QACR,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACnB,IAAI,CAAC,CAAA;QACL,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACxB,uBAAuB;YACvB,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAA;YACvC,wBAAwB;YACxB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAA;YACjB,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YAElB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAElB,mCAAmC;QACrC,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;IACtB,CAAC;IAGD,KAAK,CAAC,GAAG,CAAC,IAAY;QACpB,IAAI,CAAC,mBAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,IAAI,GAAG,mBAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;QAC3C,CAAC;QAED,yBAAyB;QACzB,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACpD,OAAM;QACR,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAA,eAAI,EAAC,IAAI,CAAC,CAAA;QACjC,MAAM,KAAK,GAAU;YACnB,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,QAAQ,CAAC,WAAW,EAAE;YAChC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;SACjB,CAAA;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAEvB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAElB,4BAA4B;IAC9B,CAAC;IAGD,4EAA4E;IAC5E,KAAK,CAAC,IAAY;QAChB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClD,OAAO,KAAK,CAAC,IAAI,CAAA;YACnB,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAGD,KAAK,CAAC,MAAM,CAAC,EAAe;QAC1B,IAAI,KAAK,GAAI,EAAE,CAAC,KAAe,CAAA;QAE/B,IAAI,KAAK,GACP,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,KAAe,EAAE,MAAW,EAAE,EAAE;YACnE,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;YAC1D,OAAO,KAAK,CAAA;QACd,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;QAGlB,6BAA6B;QAC7B,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE;YACnC,IAAI,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC;gBAC5B,EAAE,KAAK,IAAI;gBACX,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,EACxB,CAAC;gBACD,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YACtB,CAAC;QACH,CAAC,CAAC,CAAA;IAEJ,CAAC;IAGD,4BAA4B;IAC5B,KAAK,CAAC,KAAK;QACT,OAAO,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;IACzC,CAAC;IAGD,KAAK,CAAC,GAAG,CAAC,IAAc,EAAE,OAAgB;QACxC,kBAAkB;;QAElB,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAClC,KAAK,CAAC,iBAAiB,EAAE,IAAI,CAAC,gBAAgB,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAA;QAChF,KAAK,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;QAEhC,wCAAwC;QACxC,IAAI,GAAG,GAAG,CAAC,MAAM,IAAA,mBAAQ,EAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;QACrD,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;QAEnB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAA,iBAAS,EAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAE/C,+BAA+B;QAC/B,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAA;QAEpB,IAAI,EAAE,GAAgB,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAA;QAE5C,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAE,EAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;QAEvE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YACV,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAA,EAAE,aAAF,EAAE,uBAAF,EAAE,CAAE,KAAK,0CAAE,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAA;YAE7D,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,0BAA0B;gBAC1B,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YACvB,CAAC;QACH,CAAC;aACI,CAAC;YACJ,IAAI,CAAC,gBAAgB,IAAG,MAAA,EAAE,CAAC,GAAG,0CAAE,MAAM,CAAA,CAAC,CAAA;YACvC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAA;QACvB,CAAC;QAED,IAAI,CAAC,IAAI,GAAG,EAAE,CAAA;QAEd,OAAO,EAAE,CAAA;IACX,CAAC;IAGD,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAA;IACxB,CAAC;IAGD,YAAY,CAAC,EAAe;QAC1B,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC;YACX,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC;gBACtB,yCAAyC;gBAEzC,IAAI,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC;oBACvB,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;gBACd,CAAC;gBACD,yBAAyB;gBACzB,qBAAqB;gBACrB,IAAI;qBACC,CAAC;oBACJ,IAAI,CAAC,EAAE,CAAC,CAAA;gBACV,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,IAAqD;QAC5D,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YACjB,OAAO,EAAE,CAAA;QACX,CAAC;QAED,IAAI,IAAI,GAAG,EAAE,CAAA;QACb,KAAK,IAAI,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC,CAAA;YAC3B,KAAK,IAAI,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;gBACjD,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,CAAA;YAC7B,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACxB,CAAC;CACF;AAIC,sBAAK"}
|
package/lib/builder/local.ts
CHANGED
|
@@ -30,7 +30,10 @@ const local_builder: Builder = async (build: Build, ctx: BuildContext) => {
|
|
|
30
30
|
let builder = builders[name]
|
|
31
31
|
let action_path = Path.join(root, builder.load)
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
|
|
34
|
+
// clear(action_path)
|
|
35
|
+
|
|
36
|
+
|
|
34
37
|
let action = require(action_path)
|
|
35
38
|
|
|
36
39
|
if (action instanceof Promise) {
|
|
@@ -91,7 +94,7 @@ const local_builder: Builder = async (build: Build, ctx: BuildContext) => {
|
|
|
91
94
|
return { ok: false, why: 'bad-step', step: ctx.step, active: false }
|
|
92
95
|
}
|
|
93
96
|
|
|
94
|
-
|
|
97
|
+
/*
|
|
95
98
|
// Adapted from https://github.com/sindresorhus/import-fresh - Thanks!
|
|
96
99
|
function clear(path: string) {
|
|
97
100
|
let filePath = require.resolve(path)
|
|
@@ -119,6 +122,7 @@ function clear(path: string) {
|
|
|
119
122
|
}
|
|
120
123
|
|
|
121
124
|
}
|
|
125
|
+
*/
|
|
122
126
|
|
|
123
127
|
|
|
124
128
|
export {
|
package/lib/watch.ts
CHANGED
|
@@ -8,51 +8,136 @@ import type { Build, BuildResult } from './types'
|
|
|
8
8
|
import { makeBuild } from './build'
|
|
9
9
|
import { FSWatcher } from 'chokidar'
|
|
10
10
|
|
|
11
|
-
import { readFile } from 'fs/promises'
|
|
11
|
+
import { readFile, stat } from 'fs/promises'
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
const print = console.log
|
|
15
15
|
const warn = console.warn
|
|
16
16
|
|
|
17
17
|
|
|
18
|
+
type Run = {
|
|
19
|
+
canon: string
|
|
20
|
+
path: string
|
|
21
|
+
start: number
|
|
22
|
+
end: number
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type Canon = {
|
|
26
|
+
path: string
|
|
27
|
+
isFolder: boolean
|
|
28
|
+
when: number
|
|
29
|
+
}
|
|
30
|
+
|
|
18
31
|
class Watch {
|
|
19
32
|
fsw: FSWatcher
|
|
20
33
|
spec: any
|
|
21
34
|
last?: BuildResult
|
|
22
35
|
last_change_time: number
|
|
23
36
|
build: Build | undefined
|
|
37
|
+
runq: Run[]
|
|
38
|
+
doneq: Run[]
|
|
39
|
+
canons: Canon[]
|
|
40
|
+
running: boolean
|
|
24
41
|
|
|
25
42
|
constructor(spec: any) {
|
|
26
43
|
this.spec = spec
|
|
27
44
|
this.fsw = new FSWatcher()
|
|
28
45
|
this.last_change_time = 0
|
|
46
|
+
this.runq = []
|
|
47
|
+
this.doneq = []
|
|
48
|
+
this.canons = []
|
|
49
|
+
this.running = false
|
|
29
50
|
|
|
30
|
-
const run = this.run.bind(this)
|
|
51
|
+
// const run = this.run.bind(this)
|
|
52
|
+
const drain = this.drain.bind(this)
|
|
31
53
|
|
|
32
|
-
this.fsw.on('change', (
|
|
54
|
+
this.fsw.on('change', async (path: string) => {
|
|
33
55
|
// TODO: needs a much more robust queue that checks for dups,
|
|
34
56
|
// otherwise BuildContext state will have concurrency corruptions
|
|
35
57
|
// Avoid rebuilding when, for example, TS rewrites all files in dist
|
|
36
|
-
const dorun =
|
|
58
|
+
// const dorun = 1111 < Date.now() - this.last_change_time
|
|
37
59
|
// console.log('CHANGE', dorun, this.last_change_time, args)
|
|
38
60
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
61
|
+
const canon = this.canon(path)
|
|
62
|
+
|
|
63
|
+
const running = this.runq.find((run: Run) => run.canon === canon)
|
|
64
|
+
if (running) {
|
|
65
|
+
// console.log('RUNNING', canon, path)
|
|
66
|
+
return
|
|
42
67
|
}
|
|
68
|
+
|
|
69
|
+
this.runq.push({
|
|
70
|
+
canon,
|
|
71
|
+
path,
|
|
72
|
+
start: Date.now(),
|
|
73
|
+
end: -1,
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
// console.log('RUNQ-ADD', this.runq)
|
|
77
|
+
setImmediate(drain)
|
|
43
78
|
})
|
|
44
79
|
}
|
|
45
80
|
|
|
46
81
|
|
|
47
|
-
|
|
48
|
-
if (
|
|
49
|
-
|
|
82
|
+
async drain() {
|
|
83
|
+
if (this.running) {
|
|
84
|
+
return
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
this.running = true
|
|
88
|
+
let r
|
|
89
|
+
while (r = this.runq[0]) {
|
|
90
|
+
// console.log('DRAIN')
|
|
91
|
+
let br = await this.run(false, r.canon)
|
|
92
|
+
// console.log('BR', br)
|
|
93
|
+
this.runq.shift()
|
|
94
|
+
r.end = Date.now()
|
|
95
|
+
|
|
96
|
+
this.doneq.push(r)
|
|
97
|
+
|
|
98
|
+
// console.log('DONEQ', this.doneq)
|
|
99
|
+
}
|
|
100
|
+
this.running = false
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
async add(path: string) {
|
|
105
|
+
if (!Path.isAbsolute(path)) {
|
|
106
|
+
path = Path.join(this.spec.require, path)
|
|
50
107
|
}
|
|
51
|
-
|
|
108
|
+
|
|
109
|
+
// Ignore if aleady added
|
|
110
|
+
if (this.canons.find((c: Canon) => c.path === path)) {
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const fileStat = await stat(path)
|
|
115
|
+
const canon: Canon = {
|
|
116
|
+
path: path,
|
|
117
|
+
isFolder: fileStat.isDirectory(),
|
|
118
|
+
when: Date.now()
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
this.canons.push(canon)
|
|
122
|
+
|
|
123
|
+
this.fsw.add(path)
|
|
124
|
+
|
|
125
|
+
// console.log('ADD', canon)
|
|
52
126
|
}
|
|
53
127
|
|
|
54
128
|
|
|
55
|
-
|
|
129
|
+
// If path is inside a watched folder, return folder as canonical reference.
|
|
130
|
+
canon(path: string) {
|
|
131
|
+
for (const canon of this.canons) {
|
|
132
|
+
if (canon.isFolder && path.startsWith(canon.path)) {
|
|
133
|
+
return canon.path
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return path
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
async update(br: BuildResult) {
|
|
56
141
|
let build = (br.build as Build)
|
|
57
142
|
|
|
58
143
|
let files: string[] =
|
|
@@ -63,12 +148,12 @@ class Watch {
|
|
|
63
148
|
|
|
64
149
|
|
|
65
150
|
// TODO: remove deleted files
|
|
66
|
-
files.forEach((file: string) => {
|
|
151
|
+
files.forEach(async (file: string) => {
|
|
67
152
|
if ('string' === typeof (file) &&
|
|
68
153
|
'' !== file &&
|
|
69
154
|
build.opts.base !== file
|
|
70
155
|
) {
|
|
71
|
-
this.
|
|
156
|
+
await this.add(file)
|
|
72
157
|
}
|
|
73
158
|
})
|
|
74
159
|
|
|
@@ -77,13 +162,16 @@ class Watch {
|
|
|
77
162
|
|
|
78
163
|
// Returns first BuildResult
|
|
79
164
|
async start(): Promise<BuildResult> {
|
|
80
|
-
return await this.run(false)
|
|
165
|
+
return await this.run(false, '<start>')
|
|
81
166
|
}
|
|
82
167
|
|
|
83
168
|
|
|
84
|
-
async run(once?: boolean): Promise<BuildResult> {
|
|
169
|
+
async run(once?: boolean, trigger?: string): Promise<BuildResult> {
|
|
170
|
+
// console.trace()
|
|
171
|
+
|
|
85
172
|
this.last_change_time = Date.now()
|
|
86
|
-
print('\n@voxgig/model', new Date(this.last_change_time))
|
|
173
|
+
print('\n@voxgig/model', this.last_change_time, new Date(this.last_change_time))
|
|
174
|
+
print('TRIGGER:', trigger, '\n')
|
|
87
175
|
|
|
88
176
|
// TODO: build spec should not have src!
|
|
89
177
|
let src = (await readFile(this.spec.path)).toString()
|
|
@@ -103,7 +191,7 @@ class Watch {
|
|
|
103
191
|
|
|
104
192
|
if (!once) {
|
|
105
193
|
// There may be new files.
|
|
106
|
-
this.update(br)
|
|
194
|
+
await this.update(br)
|
|
107
195
|
}
|
|
108
196
|
}
|
|
109
197
|
else {
|
|
@@ -125,12 +213,14 @@ class Watch {
|
|
|
125
213
|
handleErrors(br: BuildResult) {
|
|
126
214
|
if (br.err) {
|
|
127
215
|
for (let be of br.err) {
|
|
128
|
-
if
|
|
216
|
+
// TODO: print stack if not a model error
|
|
217
|
+
|
|
218
|
+
if (be.isVal && be.msg) {
|
|
129
219
|
warn(be.msg)
|
|
130
220
|
}
|
|
131
|
-
else if (be.message) {
|
|
132
|
-
|
|
133
|
-
}
|
|
221
|
+
// else if (be.message) {
|
|
222
|
+
// warn(be.message)
|
|
223
|
+
// }
|
|
134
224
|
else {
|
|
135
225
|
warn(be)
|
|
136
226
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voxgig/model",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
4
4
|
"main": "dist/model.js",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"types": "dist/model.d.ts",
|
|
@@ -46,13 +46,13 @@
|
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@voxgig/util": "^0.0.3",
|
|
48
48
|
"aontu": "0.22.0",
|
|
49
|
-
"chokidar": "4.0.
|
|
49
|
+
"chokidar": "4.0.1"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/jest": "^29.5.13",
|
|
53
|
-
"@types/node": "22.
|
|
53
|
+
"@types/node": "22.6.1",
|
|
54
54
|
"es-jest": "^2.1.0",
|
|
55
|
-
"esbuild": "^0.
|
|
55
|
+
"esbuild": "^0.24.0",
|
|
56
56
|
"esbuild-jest": "^0.5.0",
|
|
57
57
|
"jest": "^29.7.0",
|
|
58
58
|
"typescript": "^5.6.2"
|