@inkandswitch/patchwork 0.7.0 → 0.7.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/CHANGELOG.md +25 -0
- package/dist/vite/build-info-plugin.js +4 -0
- package/dist/vite/dev-plugin.js +12 -0
- package/dist/vite/static-plugin.d.ts +2 -1
- package/dist/vite/static-plugin.js +19 -3
- package/package.json +3 -3
- package/src/vite/build-info-plugin.ts +3 -0
- package/src/vite/dev-plugin.ts +19 -0
- package/src/vite/static-plugin.ts +26 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @inkandswitch/patchwork
|
|
2
2
|
|
|
3
|
+
## 0.7.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e1374ad: Serve the `/packages/…` builtin URLs in dev. Import maps don't apply to worker
|
|
8
|
+
scripts, so code that starts one — `@automerge/automerge-repo`'s shared
|
|
9
|
+
subduction websocket worker, for instance — asks for the `/packages/…` path the
|
|
10
|
+
build emits. Nothing served those in dev, and the worker failed to fetch; the
|
|
11
|
+
dev server now redirects them to the same optimized dep the page's import map
|
|
12
|
+
points at.
|
|
13
|
+
- e1374ad: Say what's actually wrong when a `static` package declares a directory that
|
|
14
|
+
isn't there. The package resolved fine — its `"patchwork": {"static": …}` field
|
|
15
|
+
is what's wrong — and "static source not found" named neither the field nor the
|
|
16
|
+
path it pointed at. The error now quotes the declaration, gives the full path
|
|
17
|
+
that's missing, and says that a package publishing its static tree as the root
|
|
18
|
+
of its own tarball shouldn't set the field at all.
|
|
19
|
+
|
|
20
|
+
## 0.7.1
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- 8b9206d: Don't copy `static` sources or write `build-info.json` when a dev server shuts
|
|
25
|
+
down. `closeBundle` runs then too, so stopping `vite` was filling `dist/` with
|
|
26
|
+
a copy of every static source.
|
|
27
|
+
|
|
3
28
|
## 0.7.0
|
|
4
29
|
|
|
5
30
|
### Minor Changes
|
|
@@ -42,13 +42,17 @@ export function buildInfoPlugin(options = {}) {
|
|
|
42
42
|
return null;
|
|
43
43
|
let root;
|
|
44
44
|
let outDir;
|
|
45
|
+
let serve = false;
|
|
45
46
|
return {
|
|
46
47
|
name: "@patchwork/build-info",
|
|
47
48
|
configResolved(config) {
|
|
48
49
|
root = config.root;
|
|
49
50
|
outDir = join(config.root, config.build.outDir);
|
|
51
|
+
serve = config.command === "serve";
|
|
50
52
|
},
|
|
51
53
|
async closeBundle() {
|
|
54
|
+
if (serve)
|
|
55
|
+
return;
|
|
52
56
|
const sources = resolveStatic(options, root).map((source) => source.packageDirectory
|
|
53
57
|
? { from: source.from, ...describe(source.packageDirectory) }
|
|
54
58
|
: { from: source.from, revision: revision(source.path) });
|
package/dist/vite/dev-plugin.js
CHANGED
|
@@ -14,6 +14,7 @@ const stylesheets = {
|
|
|
14
14
|
[PATCHWORK_CSS]: fileURLToPath(import.meta.resolve("@inkandswitch/patchwork/global.css")),
|
|
15
15
|
[BOOTLOADER_CSS]: fileURLToPath(import.meta.resolve("@inkandswitch/patchwork-bootloader/global.css")),
|
|
16
16
|
};
|
|
17
|
+
const builtinPaths = new Map(Object.entries(builtins).map(([id, fileName]) => [fileName, id]));
|
|
17
18
|
/**
|
|
18
19
|
* Workers are `type: "module"` scripts the browser fetches directly, so import
|
|
19
20
|
* maps don't apply to them and their heavy imports have to resolve to real
|
|
@@ -92,6 +93,17 @@ export function devPlugin(options = {}) {
|
|
|
92
93
|
}
|
|
93
94
|
return;
|
|
94
95
|
}
|
|
96
|
+
// A worker script is fetched by URL, and import maps don't apply to
|
|
97
|
+
// those, so code that starts one reaches for the /packages/… path the
|
|
98
|
+
// build emits. In dev those are the optimized deps the page's import
|
|
99
|
+
// map points at — same module, one URL over.
|
|
100
|
+
const builtin = builtinPaths.get(pathname);
|
|
101
|
+
if (builtin) {
|
|
102
|
+
response.statusCode = 302;
|
|
103
|
+
response.setHeader("Location", `/@id/${encodeURI(devDependencyId(builtin))}`);
|
|
104
|
+
response.end();
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
95
107
|
const binary = wasm.get(pathname);
|
|
96
108
|
if (binary) {
|
|
97
109
|
try {
|
|
@@ -7,7 +7,8 @@ import type { PatchworkVitePluginOptions } from "./patchwork-plugin.js";
|
|
|
7
7
|
* `from` is either a package specifier or a path relative to the site root. A
|
|
8
8
|
* package says where its static tree lives with a `"patchwork": {"static":
|
|
9
9
|
* "static-dist"}` field in its own package.json; without one, the whole
|
|
10
|
-
* package directory is mounted
|
|
10
|
+
* package directory is mounted — which is what a package that publishes its
|
|
11
|
+
* static tree as the root of its own tarball wants.
|
|
11
12
|
*/
|
|
12
13
|
export interface PatchworkStaticSource {
|
|
13
14
|
from: string;
|
|
@@ -34,17 +34,28 @@ function packageDirectory(name, root) {
|
|
|
34
34
|
throw new Error(`[patchwork] can't find the package "${name}" — a static source has to be a dependency of the site`);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
+
/** A package's static tree: the directory it declares, or its root. */
|
|
38
|
+
function staticDirectory(name, directory) {
|
|
39
|
+
const declared = JSON.parse(readFileSync(join(directory, "package.json"), "utf8")).patchwork?.static;
|
|
40
|
+
if (!declared)
|
|
41
|
+
return directory;
|
|
42
|
+
const path = join(directory, declared);
|
|
43
|
+
if (!existsSync(path)) {
|
|
44
|
+
throw new Error(`[patchwork] ${name} declares "patchwork": {"static": ${JSON.stringify(declared)}}, but ${path} doesn't exist. ` +
|
|
45
|
+
`The field is a path inside the installed package — a package that publishes its static tree as the tarball's own root shouldn't set it at all.`);
|
|
46
|
+
}
|
|
47
|
+
return path;
|
|
48
|
+
}
|
|
37
49
|
export function resolveStatic(options, root) {
|
|
38
50
|
return (options.static ?? []).map((source) => {
|
|
39
51
|
const entry = typeof source === "string" ? { from: source } : source;
|
|
40
52
|
const isPath = entry.from.startsWith(".") || isAbsolute(entry.from);
|
|
41
53
|
const directory = isPath ? undefined : packageDirectory(entry.from, root);
|
|
42
54
|
const path = directory
|
|
43
|
-
?
|
|
44
|
-
.patchwork?.static ?? ".")
|
|
55
|
+
? staticDirectory(entry.from, directory)
|
|
45
56
|
: resolve(root, entry.from);
|
|
46
57
|
if (!existsSync(path)) {
|
|
47
|
-
throw new Error(`[patchwork] static source not found: ${entry.from}`);
|
|
58
|
+
throw new Error(`[patchwork] static source not found: ${entry.from} (${path})`);
|
|
48
59
|
}
|
|
49
60
|
const file = statSync(path).isFile();
|
|
50
61
|
const to = entry.to ?? "/";
|
|
@@ -112,6 +123,7 @@ export function staticPlugin(options = {}) {
|
|
|
112
123
|
let root;
|
|
113
124
|
let outDir;
|
|
114
125
|
let base = "/";
|
|
126
|
+
let serve = false;
|
|
115
127
|
let logger;
|
|
116
128
|
return {
|
|
117
129
|
name: "@patchwork/static",
|
|
@@ -120,9 +132,13 @@ export function staticPlugin(options = {}) {
|
|
|
120
132
|
root = config.root;
|
|
121
133
|
outDir = resolve(config.root, config.build.outDir);
|
|
122
134
|
base = config.base;
|
|
135
|
+
serve = config.command === "serve";
|
|
123
136
|
logger = config.logger;
|
|
124
137
|
},
|
|
125
138
|
async closeBundle() {
|
|
139
|
+
// also called when a dev server shuts down, which has nothing to copy
|
|
140
|
+
if (serve)
|
|
141
|
+
return;
|
|
126
142
|
for (const source of sources) {
|
|
127
143
|
const paths = source.file ? [""] : await files(source.path);
|
|
128
144
|
const kept = [];
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"url": "git+https://github.com/inkandswitch/patchwork-system.git",
|
|
6
6
|
"directory": "core/patchwork"
|
|
7
7
|
},
|
|
8
|
-
"version": "0.7.
|
|
8
|
+
"version": "0.7.2",
|
|
9
9
|
"author": "Ink & Switch",
|
|
10
10
|
"type": "module",
|
|
11
11
|
"license": "MIT",
|
|
@@ -44,10 +44,10 @@
|
|
|
44
44
|
"sharp": "^0.35.3",
|
|
45
45
|
"vite-plugin-wasm": "^3.6.0",
|
|
46
46
|
"@inkandswitch/patchwork-bootloader": "^0.6.2",
|
|
47
|
+
"@inkandswitch/patchwork-elements": "^6.0.0",
|
|
47
48
|
"@inkandswitch/patchwork-filesystem": "^0.2.5",
|
|
48
|
-
"@inkandswitch/patchwork-plugins": "^1.2.0",
|
|
49
49
|
"@inkandswitch/patchwork-providers": "^0.5.0",
|
|
50
|
-
"@inkandswitch/patchwork-
|
|
50
|
+
"@inkandswitch/patchwork-plugins": "^1.2.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"rollup": "^4.61.1",
|
|
@@ -49,13 +49,16 @@ export function buildInfoPlugin(
|
|
|
49
49
|
if (!options.buildInfo) return null;
|
|
50
50
|
let root: string;
|
|
51
51
|
let outDir: string;
|
|
52
|
+
let serve = false;
|
|
52
53
|
return {
|
|
53
54
|
name: "@patchwork/build-info",
|
|
54
55
|
configResolved(config) {
|
|
55
56
|
root = config.root;
|
|
56
57
|
outDir = join(config.root, config.build.outDir);
|
|
58
|
+
serve = config.command === "serve";
|
|
57
59
|
},
|
|
58
60
|
async closeBundle() {
|
|
61
|
+
if (serve) return;
|
|
59
62
|
const sources = resolveStatic(options, root).map((source) =>
|
|
60
63
|
source.packageDirectory
|
|
61
64
|
? { from: source.from, ...describe(source.packageDirectory) }
|
package/src/vite/dev-plugin.ts
CHANGED
|
@@ -23,6 +23,10 @@ const stylesheets: Record<string, string> = {
|
|
|
23
23
|
),
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
+
const builtinPaths = new Map(
|
|
27
|
+
Object.entries(builtins).map(([id, fileName]) => [fileName, id])
|
|
28
|
+
);
|
|
29
|
+
|
|
26
30
|
/**
|
|
27
31
|
* Workers are `type: "module"` scripts the browser fetches directly, so import
|
|
28
32
|
* maps don't apply to them and their heavy imports have to resolve to real
|
|
@@ -117,6 +121,21 @@ export function devPlugin(options: PatchworkVitePluginOptions = {}): Plugin {
|
|
|
117
121
|
return;
|
|
118
122
|
}
|
|
119
123
|
|
|
124
|
+
// A worker script is fetched by URL, and import maps don't apply to
|
|
125
|
+
// those, so code that starts one reaches for the /packages/… path the
|
|
126
|
+
// build emits. In dev those are the optimized deps the page's import
|
|
127
|
+
// map points at — same module, one URL over.
|
|
128
|
+
const builtin = builtinPaths.get(pathname);
|
|
129
|
+
if (builtin) {
|
|
130
|
+
response.statusCode = 302;
|
|
131
|
+
response.setHeader(
|
|
132
|
+
"Location",
|
|
133
|
+
`/@id/${encodeURI(devDependencyId(builtin))}`
|
|
134
|
+
);
|
|
135
|
+
response.end();
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
120
139
|
const binary = wasm.get(pathname);
|
|
121
140
|
if (binary) {
|
|
122
141
|
try {
|
|
@@ -22,7 +22,8 @@ import type { PatchworkVitePluginOptions } from "./patchwork-plugin.js";
|
|
|
22
22
|
* `from` is either a package specifier or a path relative to the site root. A
|
|
23
23
|
* package says where its static tree lives with a `"patchwork": {"static":
|
|
24
24
|
* "static-dist"}` field in its own package.json; without one, the whole
|
|
25
|
-
* package directory is mounted
|
|
25
|
+
* package directory is mounted — which is what a package that publishes its
|
|
26
|
+
* static tree as the root of its own tarball wants.
|
|
26
27
|
*/
|
|
27
28
|
export interface PatchworkStaticSource {
|
|
28
29
|
from: string;
|
|
@@ -87,6 +88,22 @@ function packageDirectory(name: string, root: string) {
|
|
|
87
88
|
}
|
|
88
89
|
}
|
|
89
90
|
|
|
91
|
+
/** A package's static tree: the directory it declares, or its root. */
|
|
92
|
+
function staticDirectory(name: string, directory: string) {
|
|
93
|
+
const declared = JSON.parse(
|
|
94
|
+
readFileSync(join(directory, "package.json"), "utf8")
|
|
95
|
+
).patchwork?.static;
|
|
96
|
+
if (!declared) return directory;
|
|
97
|
+
const path = join(directory, declared);
|
|
98
|
+
if (!existsSync(path)) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
`[patchwork] ${name} declares "patchwork": {"static": ${JSON.stringify(declared)}}, but ${path} doesn't exist. ` +
|
|
101
|
+
`The field is a path inside the installed package — a package that publishes its static tree as the tarball's own root shouldn't set it at all.`
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
return path;
|
|
105
|
+
}
|
|
106
|
+
|
|
90
107
|
export function resolveStatic(
|
|
91
108
|
options: PatchworkVitePluginOptions,
|
|
92
109
|
root: string
|
|
@@ -96,14 +113,12 @@ export function resolveStatic(
|
|
|
96
113
|
const isPath = entry.from.startsWith(".") || isAbsolute(entry.from);
|
|
97
114
|
const directory = isPath ? undefined : packageDirectory(entry.from, root);
|
|
98
115
|
const path = directory
|
|
99
|
-
?
|
|
100
|
-
directory,
|
|
101
|
-
JSON.parse(readFileSync(join(directory, "package.json"), "utf8"))
|
|
102
|
-
.patchwork?.static ?? "."
|
|
103
|
-
)
|
|
116
|
+
? staticDirectory(entry.from, directory)
|
|
104
117
|
: resolve(root, entry.from);
|
|
105
118
|
if (!existsSync(path)) {
|
|
106
|
-
throw new Error(
|
|
119
|
+
throw new Error(
|
|
120
|
+
`[patchwork] static source not found: ${entry.from} (${path})`
|
|
121
|
+
);
|
|
107
122
|
}
|
|
108
123
|
const file = statSync(path).isFile();
|
|
109
124
|
const to = entry.to ?? "/";
|
|
@@ -170,6 +185,7 @@ export function staticPlugin(
|
|
|
170
185
|
let root: string;
|
|
171
186
|
let outDir: string;
|
|
172
187
|
let base = "/";
|
|
188
|
+
let serve = false;
|
|
173
189
|
let logger: Logger;
|
|
174
190
|
return {
|
|
175
191
|
name: "@patchwork/static",
|
|
@@ -178,9 +194,12 @@ export function staticPlugin(
|
|
|
178
194
|
root = config.root;
|
|
179
195
|
outDir = resolve(config.root, config.build.outDir);
|
|
180
196
|
base = config.base;
|
|
197
|
+
serve = config.command === "serve";
|
|
181
198
|
logger = config.logger;
|
|
182
199
|
},
|
|
183
200
|
async closeBundle() {
|
|
201
|
+
// also called when a dev server shuts down, which has nothing to copy
|
|
202
|
+
if (serve) return;
|
|
184
203
|
for (const source of sources) {
|
|
185
204
|
const paths = source.file ? [""] : await files(source.path);
|
|
186
205
|
const kept: string[] = [];
|