@eighty4/dank 0.0.4-0 → 0.0.4-2
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/client/esbuild.js +1 -91
- package/lib/bin.ts +1 -1
- package/lib/build.ts +8 -5
- package/lib/config.ts +211 -5
- package/lib/dank.ts +14 -150
- package/lib/developer.ts +117 -0
- package/lib/esbuild.ts +146 -118
- package/lib/flags.ts +10 -4
- package/lib/html.ts +10 -14
- package/lib/metadata.ts +65 -40
- package/lib/serve.ts +94 -10
- package/lib_js/bin.js +80 -84
- package/lib_js/build.js +72 -81
- package/lib_js/build_tag.js +20 -21
- package/lib_js/config.js +158 -18
- package/lib_js/dank.js +5 -122
- package/lib_js/define.js +8 -5
- package/lib_js/esbuild.js +161 -164
- package/lib_js/flags.js +115 -114
- package/lib_js/html.js +214 -233
- package/lib_js/http.js +174 -193
- package/lib_js/metadata.js +183 -191
- package/lib_js/public.js +45 -46
- package/lib_js/serve.js +212 -230
- package/lib_js/services.js +152 -171
- package/lib_types/dank.d.ts +8 -1
- package/package.json +5 -1
package/lib_js/metadata.js
CHANGED
|
@@ -1,198 +1,190 @@
|
|
|
1
|
-
import EventEmitter from
|
|
2
|
-
import { writeFile } from
|
|
3
|
-
import { dirname, join, resolve
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
// return Array.from(this.#bundles).filter(p => p.endsWith(type))
|
|
24
|
-
// }
|
|
25
|
-
// }
|
|
26
|
-
buildRegistry() {
|
|
27
|
-
return new BuildRegistry(this.#build, this.#onBuildManifest);
|
|
28
|
-
}
|
|
29
|
-
files() {
|
|
30
|
-
const files = new Set();
|
|
31
|
-
for (const pageUrl of this.#pageUrls)
|
|
32
|
-
files.add(pageUrl === '/' ? '/index.html' : `${pageUrl}/index.html`);
|
|
33
|
-
for (const f of this.#bundles)
|
|
34
|
-
files.add(f);
|
|
35
|
-
if (this.#copiedAssets)
|
|
36
|
-
for (const f of this.#copiedAssets)
|
|
37
|
-
files.add(f);
|
|
38
|
-
return files;
|
|
39
|
-
}
|
|
40
|
-
mappedHref(lookup) {
|
|
41
|
-
const found = this.#entrypointHrefs[lookup];
|
|
42
|
-
if (found) {
|
|
43
|
-
return found;
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
throw Error(`mapped href for ${lookup} not found`);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
resolve(from, href) {
|
|
50
|
-
return resolveImpl(this.#build, from, href);
|
|
51
|
-
}
|
|
52
|
-
workerEntryPoints() {
|
|
53
|
-
return (this.#workers?.map(({ workerEntryPoint }) => ({
|
|
54
|
-
in: workerEntryPoint,
|
|
55
|
-
out: workerEntryPoint
|
|
56
|
-
.replace(/^pages[\//]/, '')
|
|
57
|
-
.replace(/\.(mj|t)s$/, '.js'),
|
|
58
|
-
})) || null);
|
|
59
|
-
}
|
|
60
|
-
workers() {
|
|
61
|
-
return this.#workers;
|
|
62
|
-
}
|
|
63
|
-
async writeManifest(buildTag) {
|
|
64
|
-
const manifest = this.#manifest(buildTag);
|
|
65
|
-
await writeFile(join(this.#build.dirs.projectRootAbs, this.#build.dirs.buildRoot, 'website.json'), JSON.stringify({
|
|
66
|
-
buildTag,
|
|
67
|
-
files: Array.from(manifest.files),
|
|
68
|
-
pageUrls: Array.from(manifest.pageUrls),
|
|
69
|
-
}, null, 4));
|
|
70
|
-
return manifest;
|
|
71
|
-
}
|
|
72
|
-
set copiedAssets(copiedAssets) {
|
|
73
|
-
this.#copiedAssets =
|
|
74
|
-
copiedAssets === null ? null : new Set(copiedAssets);
|
|
75
|
-
}
|
|
76
|
-
set pageUrls(pageUrls) {
|
|
77
|
-
this.#pageUrls = pageUrls;
|
|
78
|
-
}
|
|
79
|
-
#manifest(buildTag) {
|
|
80
|
-
return {
|
|
81
|
-
buildTag,
|
|
82
|
-
files: this.files(),
|
|
83
|
-
pageUrls: new Set(this.#pageUrls),
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
#onBuildManifest = (build) => {
|
|
87
|
-
// collect built bundle entrypoint hrefs
|
|
88
|
-
for (const [outPath, entrypoint] of Object.entries(build.bundles)) {
|
|
89
|
-
this.#bundles.add(outPath);
|
|
90
|
-
if (entrypoint) {
|
|
91
|
-
this.#entrypointHrefs[entrypoint] = outPath;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
// determine if worker entrypoints have changed
|
|
95
|
-
let updatedWorkerEntrypoints = false;
|
|
96
|
-
const previousWorkers = this.#workers === null
|
|
97
|
-
? null
|
|
98
|
-
: new Set(this.#workers.map(w => w.workerEntryPoint));
|
|
99
|
-
if (build.workers) {
|
|
100
|
-
if (!previousWorkers ||
|
|
101
|
-
previousWorkers.size !==
|
|
102
|
-
new Set(build.workers.map(w => w.workerEntryPoint)).size) {
|
|
103
|
-
updatedWorkerEntrypoints = true;
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
updatedWorkerEntrypoints = !build.workers.every(w => previousWorkers.has(w.workerEntryPoint));
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
else if (previousWorkers) {
|
|
110
|
-
updatedWorkerEntrypoints = true;
|
|
111
|
-
}
|
|
112
|
-
// merge unique entrypoints from built workers with registry state
|
|
113
|
-
// todo filtering out unique occurrences of clientScript and workerUrl
|
|
114
|
-
// drops reporting/summary/debugging capabilities, but currently
|
|
115
|
-
// this.#workers is used for unique worker/client entrypoints
|
|
116
|
-
if (build.workers) {
|
|
117
|
-
if (!this.#workers) {
|
|
118
|
-
this.#workers = build.workers;
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
for (const w of build.workers) {
|
|
122
|
-
const found = this.#workers.find(w2 => {
|
|
123
|
-
return (w.dependentEntryPoint === w2.dependentEntryPoint &&
|
|
124
|
-
w.workerEntryPoint === w2.workerEntryPoint);
|
|
125
|
-
});
|
|
126
|
-
if (!found) {
|
|
127
|
-
this.#workers.push(w);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
if (updatedWorkerEntrypoints) {
|
|
133
|
-
this.emit('workers');
|
|
134
|
-
}
|
|
135
|
-
};
|
|
1
|
+
import EventEmitter from "node:events";
|
|
2
|
+
import { writeFile } from "node:fs/promises";
|
|
3
|
+
import { dirname, join, resolve } from "node:path";
|
|
4
|
+
class ResolverImpl {
|
|
5
|
+
#dirs;
|
|
6
|
+
constructor(dirs) {
|
|
7
|
+
this.#dirs = dirs;
|
|
8
|
+
}
|
|
9
|
+
isProjectSubpathInPagesDir(p) {
|
|
10
|
+
return resolve(join(this.#dirs.projectResolved, p)).startsWith(this.#dirs.pagesResolved);
|
|
11
|
+
}
|
|
12
|
+
isPagesSubpathInPagesDir(p) {
|
|
13
|
+
return this.isProjectSubpathInPagesDir(join(this.#dirs.pages, p));
|
|
14
|
+
}
|
|
15
|
+
resolveHrefInPagesDir(from, href) {
|
|
16
|
+
const p = join(dirname(from), href);
|
|
17
|
+
if (this.isProjectSubpathInPagesDir(p)) {
|
|
18
|
+
return p;
|
|
19
|
+
} else {
|
|
20
|
+
return "outofbounds";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
136
23
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
24
|
+
class WebsiteRegistry extends EventEmitter {
|
|
25
|
+
#build;
|
|
26
|
+
// paths of bundled esbuild outputs
|
|
27
|
+
#bundles = /* @__PURE__ */ new Set();
|
|
28
|
+
// public dir assets
|
|
29
|
+
#copiedAssets = null;
|
|
30
|
+
// map of entrypoints to their output path
|
|
31
|
+
#entrypointHrefs = {};
|
|
32
|
+
#pageUrls = [];
|
|
33
|
+
#resolver;
|
|
34
|
+
#workers = null;
|
|
35
|
+
constructor(build) {
|
|
36
|
+
super();
|
|
37
|
+
this.#build = build;
|
|
38
|
+
this.#resolver = new ResolverImpl(build.dirs);
|
|
39
|
+
}
|
|
40
|
+
set copiedAssets(copiedAssets) {
|
|
41
|
+
this.#copiedAssets = copiedAssets === null ? null : new Set(copiedAssets);
|
|
42
|
+
}
|
|
43
|
+
set pageUrls(pageUrls) {
|
|
44
|
+
this.#pageUrls = pageUrls;
|
|
45
|
+
}
|
|
46
|
+
get resolver() {
|
|
47
|
+
return this.#resolver;
|
|
48
|
+
}
|
|
49
|
+
// bundleOutputs(type?: 'css' | 'js'): Array<string> {
|
|
50
|
+
// if (!type) {
|
|
51
|
+
// return Array.from(this.#bundles)
|
|
52
|
+
// } else {
|
|
53
|
+
// return Array.from(this.#bundles).filter(p => p.endsWith(type))
|
|
54
|
+
// }
|
|
55
|
+
// }
|
|
56
|
+
buildRegistry() {
|
|
57
|
+
return new BuildRegistry(this.#build, this.#onBuildManifest);
|
|
58
|
+
}
|
|
59
|
+
files() {
|
|
60
|
+
const files = /* @__PURE__ */ new Set();
|
|
61
|
+
for (const pageUrl of this.#pageUrls)
|
|
62
|
+
files.add(pageUrl === "/" ? "/index.html" : `${pageUrl}/index.html`);
|
|
63
|
+
for (const f of this.#bundles)
|
|
64
|
+
files.add(f);
|
|
65
|
+
if (this.#copiedAssets)
|
|
66
|
+
for (const f of this.#copiedAssets)
|
|
67
|
+
files.add(f);
|
|
68
|
+
return files;
|
|
69
|
+
}
|
|
70
|
+
mappedHref(lookup) {
|
|
71
|
+
const found = this.#entrypointHrefs[lookup];
|
|
72
|
+
if (found) {
|
|
73
|
+
return found;
|
|
74
|
+
} else {
|
|
75
|
+
throw Error(`mapped href for ${lookup} not found`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
workerEntryPoints() {
|
|
79
|
+
return this.#workers?.map(({ workerEntryPoint }) => ({
|
|
80
|
+
in: workerEntryPoint,
|
|
81
|
+
out: workerEntryPoint.replace(/^pages[\//]/, "").replace(/\.(mj|t)s$/, ".js")
|
|
82
|
+
})) || null;
|
|
83
|
+
}
|
|
84
|
+
workers() {
|
|
85
|
+
return this.#workers;
|
|
86
|
+
}
|
|
87
|
+
async writeManifest(buildTag) {
|
|
88
|
+
const manifest = this.#manifest(buildTag);
|
|
89
|
+
await writeFile(join(this.#build.dirs.projectRootAbs, this.#build.dirs.buildRoot, "website.json"), JSON.stringify({
|
|
90
|
+
buildTag,
|
|
91
|
+
files: Array.from(manifest.files),
|
|
92
|
+
pageUrls: Array.from(manifest.pageUrls)
|
|
93
|
+
}, null, 4));
|
|
94
|
+
return manifest;
|
|
95
|
+
}
|
|
96
|
+
#manifest(buildTag) {
|
|
97
|
+
return {
|
|
98
|
+
buildTag,
|
|
99
|
+
files: this.files(),
|
|
100
|
+
pageUrls: new Set(this.#pageUrls)
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
#onBuildManifest = (build) => {
|
|
104
|
+
for (const [outPath, entrypoint] of Object.entries(build.bundles)) {
|
|
105
|
+
this.#bundles.add(outPath);
|
|
106
|
+
if (entrypoint) {
|
|
107
|
+
this.#entrypointHrefs[entrypoint] = outPath;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
let updatedWorkerEntrypoints = false;
|
|
111
|
+
const previousWorkers = this.#workers === null ? null : new Set(this.#workers.map((w) => w.workerEntryPoint));
|
|
112
|
+
if (build.workers) {
|
|
113
|
+
if (!previousWorkers || previousWorkers.size !== new Set(build.workers.map((w) => w.workerEntryPoint)).size) {
|
|
114
|
+
updatedWorkerEntrypoints = true;
|
|
115
|
+
} else {
|
|
116
|
+
updatedWorkerEntrypoints = !build.workers.every((w) => previousWorkers.has(w.workerEntryPoint));
|
|
117
|
+
}
|
|
118
|
+
} else if (previousWorkers) {
|
|
119
|
+
updatedWorkerEntrypoints = true;
|
|
120
|
+
}
|
|
121
|
+
if (build.workers) {
|
|
122
|
+
if (!this.#workers) {
|
|
123
|
+
this.#workers = build.workers;
|
|
124
|
+
} else {
|
|
125
|
+
for (const w of build.workers) {
|
|
126
|
+
const found = this.#workers.find((w2) => {
|
|
127
|
+
return w.dependentEntryPoint === w2.dependentEntryPoint && w.workerEntryPoint === w2.workerEntryPoint;
|
|
128
|
+
});
|
|
129
|
+
if (!found) {
|
|
130
|
+
this.#workers.push(w);
|
|
131
|
+
}
|
|
178
132
|
}
|
|
179
|
-
|
|
180
|
-
bundles,
|
|
181
|
-
workers,
|
|
182
|
-
});
|
|
133
|
+
}
|
|
183
134
|
}
|
|
184
|
-
|
|
185
|
-
|
|
135
|
+
if (updatedWorkerEntrypoints) {
|
|
136
|
+
this.emit("workers");
|
|
186
137
|
}
|
|
138
|
+
};
|
|
187
139
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
140
|
+
class BuildRegistry {
|
|
141
|
+
#onComplete;
|
|
142
|
+
#resolver;
|
|
143
|
+
#workers = null;
|
|
144
|
+
constructor(build, onComplete) {
|
|
145
|
+
this.#onComplete = onComplete;
|
|
146
|
+
this.#resolver = new ResolverImpl(build.dirs);
|
|
147
|
+
}
|
|
148
|
+
get resolver() {
|
|
149
|
+
return this.#resolver;
|
|
150
|
+
}
|
|
151
|
+
// resolve web worker imported by a webpage module
|
|
152
|
+
addWorker(worker) {
|
|
153
|
+
if (!this.#workers) {
|
|
154
|
+
this.#workers = [worker];
|
|
155
|
+
} else {
|
|
156
|
+
this.#workers.push(worker);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
completeBuild(result) {
|
|
160
|
+
const bundles = {};
|
|
161
|
+
for (const [outPath, output] of Object.entries(result.metafile.outputs)) {
|
|
162
|
+
bundles[outPath.replace(/^build[/\\]dist/, "")] = output.entryPoint || null;
|
|
163
|
+
}
|
|
164
|
+
let workers = null;
|
|
165
|
+
if (this.#workers) {
|
|
166
|
+
workers = [];
|
|
167
|
+
for (const output of Object.values(result.metafile.outputs)) {
|
|
168
|
+
if (!output.entryPoint)
|
|
169
|
+
continue;
|
|
170
|
+
const inputs = Object.keys(output.inputs);
|
|
171
|
+
for (const worker of this.#workers) {
|
|
172
|
+
if (inputs.includes(worker.clientScript)) {
|
|
173
|
+
workers.push({
|
|
174
|
+
...worker,
|
|
175
|
+
dependentEntryPoint: output.entryPoint
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
197
180
|
}
|
|
181
|
+
this.#onComplete({
|
|
182
|
+
bundles,
|
|
183
|
+
workers
|
|
184
|
+
});
|
|
185
|
+
}
|
|
198
186
|
}
|
|
187
|
+
export {
|
|
188
|
+
BuildRegistry,
|
|
189
|
+
WebsiteRegistry
|
|
190
|
+
};
|
package/lib_js/public.js
CHANGED
|
@@ -1,51 +1,50 @@
|
|
|
1
|
-
import { copyFile, mkdir, readdir, stat } from
|
|
2
|
-
import { platform } from
|
|
3
|
-
import { join } from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
throw Error('./public cannot be a file');
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
catch (e) {
|
|
16
|
-
return null;
|
|
1
|
+
import { copyFile, mkdir, readdir, stat } from "node:fs/promises";
|
|
2
|
+
import { platform } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
async function copyAssets(build) {
|
|
5
|
+
try {
|
|
6
|
+
const stats = await stat(build.dirs.public);
|
|
7
|
+
if (stats.isDirectory()) {
|
|
8
|
+
await mkdir(build.dirs.buildDist, { recursive: true });
|
|
9
|
+
return await recursiveCopyAssets(build);
|
|
10
|
+
} else {
|
|
11
|
+
throw Error("./public cannot be a file");
|
|
17
12
|
}
|
|
13
|
+
} catch (e) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
18
16
|
}
|
|
19
|
-
const IGNORE = platform() ===
|
|
20
|
-
async function recursiveCopyAssets(build, dir =
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
madeDir = true;
|
|
40
|
-
}
|
|
41
|
-
await copyFile(join(listingDir, p), join(to, p));
|
|
42
|
-
copied.push('/' + join(dir, p).replaceAll('\\', '/'));
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
catch (e) {
|
|
46
|
-
console.error('stat error', e);
|
|
47
|
-
process.exit(1);
|
|
17
|
+
const IGNORE = platform() === "darwin" ? [".DS_Store"] : [];
|
|
18
|
+
async function recursiveCopyAssets(build, dir = "") {
|
|
19
|
+
const copied = [];
|
|
20
|
+
const to = join(build.dirs.buildDist, dir);
|
|
21
|
+
let madeDir = dir === "";
|
|
22
|
+
const listingDir = join(build.dirs.public, dir);
|
|
23
|
+
for (const p of await readdir(listingDir)) {
|
|
24
|
+
if (IGNORE.includes(p)) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const stats = await stat(join(listingDir, p));
|
|
29
|
+
if (stats.isDirectory()) {
|
|
30
|
+
copied.push(...await recursiveCopyAssets(build, join(dir, p)));
|
|
31
|
+
} else {
|
|
32
|
+
if (!madeDir) {
|
|
33
|
+
await mkdir(join(build.dirs.buildDist, dir), {
|
|
34
|
+
recursive: true
|
|
35
|
+
});
|
|
36
|
+
madeDir = true;
|
|
48
37
|
}
|
|
38
|
+
await copyFile(join(listingDir, p), join(to, p));
|
|
39
|
+
copied.push("/" + join(dir, p).replaceAll("\\", "/"));
|
|
40
|
+
}
|
|
41
|
+
} catch (e) {
|
|
42
|
+
console.error("stat error", e);
|
|
43
|
+
process.exit(1);
|
|
49
44
|
}
|
|
50
|
-
|
|
45
|
+
}
|
|
46
|
+
return copied;
|
|
51
47
|
}
|
|
48
|
+
export {
|
|
49
|
+
copyAssets
|
|
50
|
+
};
|