vite-plugin-cross-origin-storage 2.0.2 → 2.0.3

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/index.d.mts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { CosManifest } from "./loader.mjs";
2
2
  import { Plugin } from "vite";
3
-
4
3
  //#region src/index.d.ts
5
4
  interface CosPluginOptions {
6
5
  /**
package/dist/index.mjs CHANGED
@@ -4,7 +4,6 @@ import { fileURLToPath } from "node:url";
4
4
  import MagicString from "magic-string";
5
5
  import { rolldown } from "rolldown";
6
6
  import { parseAst } from "rolldown/parseAst";
7
-
8
7
  //#region src/index.ts
9
8
  const MANIFEST_PLACEHOLDER = "__COS_MANIFEST__";
10
9
  /**
@@ -24,6 +23,14 @@ function defaultLoaderEntry() {
24
23
  function contentSpecifier(hash) {
25
24
  return `${RECIPE}:${hash}`;
26
25
  }
26
+ /** Recover the npm package name from a resolved module id's `node_modules` segment. */
27
+ function packageNameFromId(id) {
28
+ const index = id.lastIndexOf("/node_modules/");
29
+ if (index === -1) return;
30
+ const [first, second] = id.slice(index + 14).split("/");
31
+ if (!first) return;
32
+ return first.startsWith("@") && second ? `${first}/${second}` : first;
33
+ }
27
34
  function toMatchers(packages) {
28
35
  return packages.map((p) => typeof p === "string" ? new RegExp(`^${p}$`) : p);
29
36
  }
@@ -63,6 +70,11 @@ function collectImportSources(code) {
63
70
  start: source.start,
64
71
  end: source.end
65
72
  });
73
+ else if (source?.type === "TemplateLiteral" && source.expressions?.length === 0 && source.quasis?.length === 1 && typeof source.quasis[0]?.value?.cooked === "string" && typeof source.start === "number" && typeof source.end === "number") sources.push({
74
+ value: source.quasis[0].value.cooked,
75
+ start: source.start,
76
+ end: source.end
77
+ });
66
78
  }
67
79
  for (const key in record) if (key !== "type") visit(record[key]);
68
80
  };
@@ -190,7 +202,8 @@ function cosPlugin(options) {
190
202
  hashes.set(id, hash);
191
203
  managed[contentSpecifier(hash)] = {
192
204
  file: `${hash}.js`,
193
- hash
205
+ hash,
206
+ name: packageNameFromId(id)
194
207
  };
195
208
  this.emitFile({
196
209
  type: "asset",
@@ -232,6 +245,5 @@ function cosPlugin(options) {
232
245
  }
233
246
  };
234
247
  }
235
-
236
248
  //#endregion
237
- export { cosPlugin, cosPlugin as default };
249
+ export { cosPlugin, cosPlugin as default };
package/dist/loader.d.mts CHANGED
@@ -1,20 +1,8 @@
1
1
  //#region src/loader.d.ts
2
2
  declare global {
3
- interface Navigator {
4
- crossOriginStorage?: {
5
- requestFileHandles: (descriptors: Array<{
6
- algorithm: string;
7
- value: string;
8
- }>, options?: {
9
- create?: boolean;
10
- }) => Promise<Array<{
11
- getFile: () => Promise<File>;
12
- createWritable: () => Promise<{
13
- write: (data: Blob) => Promise<void>;
14
- close: () => Promise<void>;
15
- }>;
16
- }>>;
17
- };
3
+ interface Window {
4
+ /** The manifest the loader ran with, exposed for introspection (e.g. devtools, demo UIs). */
5
+ __cosManifest?: CosManifest;
18
6
  }
19
7
  }
20
8
  interface CosManifest {
@@ -28,10 +16,15 @@ interface CosManifest {
28
16
  specifier: string;
29
17
  file: string;
30
18
  };
31
- /** Map of content-addressed specifier to `{ file, hash }` for every COS-managed chunk. */
19
+ /**
20
+ * Map of content-addressed specifier to `{ file, hash, name }` for every COS-managed chunk.
21
+ * `name` is the npm package the chunk was bundled from (e.g. `vue`, `@vue/reactivity`), when
22
+ * it could be derived from the resolved module path; absent for chunks it couldn't be.
23
+ */
32
24
  chunks: Record<string, {
33
25
  file: string;
34
26
  hash: string;
27
+ name?: string;
35
28
  }>;
36
29
  }
37
30
  //#endregion
@@ -1,7 +1,5 @@
1
1
  import { runCosLoader } from "./loader.mjs";
2
-
3
2
  //#region src/loader.entry.ts
4
3
  runCosLoader(__COS_MANIFEST__);
5
-
6
4
  //#endregion
7
- export { };
5
+ export {};
package/dist/loader.mjs CHANGED
@@ -1,17 +1,21 @@
1
1
  //#region src/loader.ts
2
2
  async function runCosLoader(manifest) {
3
+ window.__cosManifest = manifest;
3
4
  const cos = navigator.crossOriginStorage;
4
5
  const imports = {};
6
+ let cosQueue = Promise.resolve();
7
+ const enqueue = (task) => {
8
+ const result = cosQueue.then(task, task);
9
+ cosQueue = result.catch(() => {});
10
+ return result;
11
+ };
5
12
  async function resolveChunk(hash, file) {
6
13
  if (cos) try {
7
- const [handle] = await cos.requestFileHandles([{
14
+ const blob = await (await enqueue(() => cos.requestFileHandle({
8
15
  algorithm: "SHA-256",
9
16
  value: hash
10
- }]);
11
- if (handle) {
12
- const blob = await handle.getFile();
13
- return URL.createObjectURL(new Blob([blob], { type: "text/javascript" }));
14
- }
17
+ }))).getFile();
18
+ return URL.createObjectURL(new Blob([blob], { type: "text/javascript" }));
15
19
  } catch (error) {
16
20
  if (error?.name !== "NotFoundError") console.error("[cos] lookup failed", error);
17
21
  }
@@ -21,15 +25,17 @@ async function runCosLoader(manifest) {
21
25
  if (contentType && !/javascript|ecmascript/i.test(contentType)) throw new Error(`[cos] chunk ${file} served as ${contentType}, expected JavaScript`);
22
26
  const blob = new Blob([await response.blob()], { type: "text/javascript" });
23
27
  if (cos) try {
24
- const [handle] = await cos.requestFileHandles([{
25
- algorithm: "SHA-256",
26
- value: hash
27
- }], { create: true });
28
- if (handle) {
29
- const writable = await handle.createWritable();
28
+ await enqueue(async () => {
29
+ const writable = await (await cos.requestFileHandle({
30
+ algorithm: "SHA-256",
31
+ value: hash
32
+ }, {
33
+ create: true,
34
+ origins: "*"
35
+ })).createWritable();
30
36
  await writable.write(blob);
31
37
  await writable.close();
32
- }
38
+ });
33
39
  } catch (error) {
34
40
  console.error("[cos] store failed", error);
35
41
  }
@@ -49,6 +55,5 @@ async function runCosLoader(manifest) {
49
55
  manifest.entry.specifier
50
56
  );
51
57
  }
52
-
53
58
  //#endregion
54
- export { runCosLoader };
59
+ export { runCosLoader };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vite-plugin-cross-origin-storage",
3
3
  "type": "module",
4
- "version": "2.0.2",
4
+ "version": "2.0.3",
5
5
  "description": "Vite plugin to extract shared dependencies into content-addressed chunks loaded from Cross-Origin Storage",
6
6
  "author": {
7
7
  "name": "Daniel Roe",
@@ -47,20 +47,21 @@
47
47
  },
48
48
  "dependencies": {
49
49
  "magic-string": "^0.30.21",
50
- "rolldown": "1.1.0"
50
+ "rolldown": "1.2.0"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/node": "latest",
54
- "eslint": "^10.4.1",
55
- "hookable": "^5.5.3",
56
- "playwright-core": "^1.61.1",
57
- "tsdown": "^0.20.3",
58
- "typescript": "~6.0.3",
59
- "unhead": "^2.1.0",
60
- "vite": "^7.3.5",
61
- "vite8": "npm:vite@8.1.0",
62
- "vitest": "^4.1.8",
63
- "vue": "3.5.39"
54
+ "@types/wicg-cross-origin-storage": "2026.7.0",
55
+ "eslint": "10.7.0",
56
+ "hookable": "6.1.1",
57
+ "playwright-core": "1.61.1",
58
+ "tsdown": "0.22.9",
59
+ "typescript": "6.0.3",
60
+ "unhead": "3.1.8",
61
+ "vite": "8.1.4",
62
+ "vite8": "npm:vite@8.1.4",
63
+ "vitest": "4.1.10",
64
+ "vue": "3.5.40"
64
65
  },
65
66
  "scripts": {
66
67
  "build": "tsdown",