@rockhall/electron-offline-content 0.4.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.
Files changed (196) hide show
  1. package/CHANGELOG.md +384 -0
  2. package/LICENSE +21 -0
  3. package/README.md +794 -0
  4. package/dist/internal/asset-file-name.cjs +13 -0
  5. package/dist/internal/asset-file-name.cjs.map +1 -0
  6. package/dist/internal/asset-file-name.d.cts +6 -0
  7. package/dist/internal/asset-file-name.d.cts.map +1 -0
  8. package/dist/internal/asset-file-name.d.ts +6 -0
  9. package/dist/internal/asset-file-name.d.ts.map +1 -0
  10. package/dist/internal/asset-file-name.js +12 -0
  11. package/dist/internal/asset-file-name.js.map +1 -0
  12. package/dist/internal/asset-key.cjs +30 -0
  13. package/dist/internal/asset-key.cjs.map +1 -0
  14. package/dist/internal/asset-key.d.cts +19 -0
  15. package/dist/internal/asset-key.d.cts.map +1 -0
  16. package/dist/internal/asset-key.d.ts +19 -0
  17. package/dist/internal/asset-key.d.ts.map +1 -0
  18. package/dist/internal/asset-key.js +27 -0
  19. package/dist/internal/asset-key.js.map +1 -0
  20. package/dist/internal/log-format.cjs +98 -0
  21. package/dist/internal/log-format.cjs.map +1 -0
  22. package/dist/internal/log-format.d.cts +10 -0
  23. package/dist/internal/log-format.d.cts.map +1 -0
  24. package/dist/internal/log-format.d.ts +10 -0
  25. package/dist/internal/log-format.d.ts.map +1 -0
  26. package/dist/internal/log-format.js +97 -0
  27. package/dist/internal/log-format.js.map +1 -0
  28. package/dist/internal/media-kind.cjs +46 -0
  29. package/dist/internal/media-kind.cjs.map +1 -0
  30. package/dist/internal/media-kind.d.cts +20 -0
  31. package/dist/internal/media-kind.d.cts.map +1 -0
  32. package/dist/internal/media-kind.d.ts +20 -0
  33. package/dist/internal/media-kind.d.ts.map +1 -0
  34. package/dist/internal/media-kind.js +45 -0
  35. package/dist/internal/media-kind.js.map +1 -0
  36. package/dist/internal/url-warn.cjs +14 -0
  37. package/dist/internal/url-warn.cjs.map +1 -0
  38. package/dist/internal/url-warn.d.cts +10 -0
  39. package/dist/internal/url-warn.d.cts.map +1 -0
  40. package/dist/internal/url-warn.d.ts +10 -0
  41. package/dist/internal/url-warn.d.ts.map +1 -0
  42. package/dist/internal/url-warn.js +13 -0
  43. package/dist/internal/url-warn.js.map +1 -0
  44. package/dist/internal/validation.cjs +222 -0
  45. package/dist/internal/validation.cjs.map +1 -0
  46. package/dist/internal/validation.d.cts +78 -0
  47. package/dist/internal/validation.d.cts.map +1 -0
  48. package/dist/internal/validation.d.ts +78 -0
  49. package/dist/internal/validation.d.ts.map +1 -0
  50. package/dist/internal/validation.js +196 -0
  51. package/dist/internal/validation.js.map +1 -0
  52. package/dist/main/asset-download.cjs +265 -0
  53. package/dist/main/asset-download.cjs.map +1 -0
  54. package/dist/main/asset-download.d.cts +12 -0
  55. package/dist/main/asset-download.d.cts.map +1 -0
  56. package/dist/main/asset-download.d.ts +12 -0
  57. package/dist/main/asset-download.d.ts.map +1 -0
  58. package/dist/main/asset-download.js +263 -0
  59. package/dist/main/asset-download.js.map +1 -0
  60. package/dist/main/database.cjs +473 -0
  61. package/dist/main/database.cjs.map +1 -0
  62. package/dist/main/database.d.cts +81 -0
  63. package/dist/main/database.d.cts.map +1 -0
  64. package/dist/main/database.d.ts +81 -0
  65. package/dist/main/database.d.ts.map +1 -0
  66. package/dist/main/database.js +472 -0
  67. package/dist/main/database.js.map +1 -0
  68. package/dist/main/index.cjs +22 -0
  69. package/dist/main/index.d.cts +7 -0
  70. package/dist/main/index.d.ts +7 -0
  71. package/dist/main/index.js +7 -0
  72. package/dist/main/media-cache.cjs +862 -0
  73. package/dist/main/media-cache.cjs.map +1 -0
  74. package/dist/main/media-cache.d.cts +134 -0
  75. package/dist/main/media-cache.d.cts.map +1 -0
  76. package/dist/main/media-cache.d.ts +134 -0
  77. package/dist/main/media-cache.d.ts.map +1 -0
  78. package/dist/main/media-cache.js +854 -0
  79. package/dist/main/media-cache.js.map +1 -0
  80. package/dist/main/storage-root-lock.cjs +124 -0
  81. package/dist/main/storage-root-lock.cjs.map +1 -0
  82. package/dist/main/storage-root-lock.d.cts +11 -0
  83. package/dist/main/storage-root-lock.d.cts.map +1 -0
  84. package/dist/main/storage-root-lock.d.ts +11 -0
  85. package/dist/main/storage-root-lock.d.ts.map +1 -0
  86. package/dist/main/storage-root-lock.js +120 -0
  87. package/dist/main/storage-root-lock.js.map +1 -0
  88. package/dist/main/store.cjs +197 -0
  89. package/dist/main/store.cjs.map +1 -0
  90. package/dist/main/store.d.cts +83 -0
  91. package/dist/main/store.d.cts.map +1 -0
  92. package/dist/main/store.d.ts +83 -0
  93. package/dist/main/store.d.ts.map +1 -0
  94. package/dist/main/store.js +195 -0
  95. package/dist/main/store.js.map +1 -0
  96. package/dist/preload/index.cjs +36 -0
  97. package/dist/preload/index.cjs.map +1 -0
  98. package/dist/preload/index.d.cts +14 -0
  99. package/dist/preload/index.d.cts.map +1 -0
  100. package/dist/preload/index.d.ts +14 -0
  101. package/dist/preload/index.d.ts.map +1 -0
  102. package/dist/preload/index.js +34 -0
  103. package/dist/preload/index.js.map +1 -0
  104. package/dist/react/index.cjs +199 -0
  105. package/dist/react/index.cjs.map +1 -0
  106. package/dist/react/index.d.cts +50 -0
  107. package/dist/react/index.d.cts.map +1 -0
  108. package/dist/react/index.d.ts +50 -0
  109. package/dist/react/index.d.ts.map +1 -0
  110. package/dist/react/index.js +191 -0
  111. package/dist/react/index.js.map +1 -0
  112. package/dist/renderer/helpers.cjs +36 -0
  113. package/dist/renderer/helpers.cjs.map +1 -0
  114. package/dist/renderer/helpers.d.cts +11 -0
  115. package/dist/renderer/helpers.d.cts.map +1 -0
  116. package/dist/renderer/helpers.d.ts +11 -0
  117. package/dist/renderer/helpers.d.ts.map +1 -0
  118. package/dist/renderer/helpers.js +35 -0
  119. package/dist/renderer/helpers.js.map +1 -0
  120. package/dist/renderer/index.cjs +20 -0
  121. package/dist/renderer/index.cjs.map +1 -0
  122. package/dist/renderer/index.d.cts +14 -0
  123. package/dist/renderer/index.d.cts.map +1 -0
  124. package/dist/renderer/index.d.ts +14 -0
  125. package/dist/renderer/index.d.ts.map +1 -0
  126. package/dist/renderer/index.js +14 -0
  127. package/dist/renderer/index.js.map +1 -0
  128. package/dist/renderer/runtime.cjs +278 -0
  129. package/dist/renderer/runtime.cjs.map +1 -0
  130. package/dist/renderer/runtime.d.cts +35 -0
  131. package/dist/renderer/runtime.d.cts.map +1 -0
  132. package/dist/renderer/runtime.d.ts +35 -0
  133. package/dist/renderer/runtime.d.ts.map +1 -0
  134. package/dist/renderer/runtime.js +273 -0
  135. package/dist/renderer/runtime.js.map +1 -0
  136. package/dist/renderer/window-globals.d.cts +9 -0
  137. package/dist/renderer/window-globals.d.cts.map +1 -0
  138. package/dist/renderer/window-globals.d.ts +9 -0
  139. package/dist/renderer/window-globals.d.ts.map +1 -0
  140. package/dist/shared/errors.cjs +102 -0
  141. package/dist/shared/errors.cjs.map +1 -0
  142. package/dist/shared/errors.d.cts +45 -0
  143. package/dist/shared/errors.d.cts.map +1 -0
  144. package/dist/shared/errors.d.ts +45 -0
  145. package/dist/shared/errors.d.ts.map +1 -0
  146. package/dist/shared/errors.js +93 -0
  147. package/dist/shared/errors.js.map +1 -0
  148. package/dist/shared/ipc.cjs +14 -0
  149. package/dist/shared/ipc.cjs.map +1 -0
  150. package/dist/shared/ipc.d.cts +12 -0
  151. package/dist/shared/ipc.d.cts.map +1 -0
  152. package/dist/shared/ipc.d.ts +12 -0
  153. package/dist/shared/ipc.d.ts.map +1 -0
  154. package/dist/shared/ipc.js +13 -0
  155. package/dist/shared/ipc.js.map +1 -0
  156. package/dist/shared/normalize.cjs +19 -0
  157. package/dist/shared/normalize.cjs.map +1 -0
  158. package/dist/shared/normalize.d.cts +11 -0
  159. package/dist/shared/normalize.d.cts.map +1 -0
  160. package/dist/shared/normalize.d.ts +11 -0
  161. package/dist/shared/normalize.d.ts.map +1 -0
  162. package/dist/shared/normalize.js +18 -0
  163. package/dist/shared/normalize.js.map +1 -0
  164. package/dist/shared/pagination.cjs +32 -0
  165. package/dist/shared/pagination.cjs.map +1 -0
  166. package/dist/shared/pagination.d.cts +14 -0
  167. package/dist/shared/pagination.d.cts.map +1 -0
  168. package/dist/shared/pagination.d.ts +14 -0
  169. package/dist/shared/pagination.d.ts.map +1 -0
  170. package/dist/shared/pagination.js +28 -0
  171. package/dist/shared/pagination.js.map +1 -0
  172. package/dist/shared/stem.cjs +16 -0
  173. package/dist/shared/stem.cjs.map +1 -0
  174. package/dist/shared/stem.d.cts +6 -0
  175. package/dist/shared/stem.d.cts.map +1 -0
  176. package/dist/shared/stem.d.ts +6 -0
  177. package/dist/shared/stem.d.ts.map +1 -0
  178. package/dist/shared/stem.js +14 -0
  179. package/dist/shared/stem.js.map +1 -0
  180. package/dist/shared/types.cjs +15 -0
  181. package/dist/shared/types.cjs.map +1 -0
  182. package/dist/shared/types.d.cts +234 -0
  183. package/dist/shared/types.d.cts.map +1 -0
  184. package/dist/shared/types.d.ts +234 -0
  185. package/dist/shared/types.d.ts.map +1 -0
  186. package/dist/shared/types.js +14 -0
  187. package/dist/shared/types.js.map +1 -0
  188. package/package.json +120 -0
  189. package/skills/authenticated-downloads/SKILL.md +203 -0
  190. package/skills/cache-configuration/SKILL.md +357 -0
  191. package/skills/cache-configuration/references/options.md +356 -0
  192. package/skills/getting-started/SKILL.md +407 -0
  193. package/skills/production-checklist/SKILL.md +397 -0
  194. package/skills/react-rendering/SKILL.md +424 -0
  195. package/skills/react-rendering/references/hooks.md +443 -0
  196. package/skills/store-authoring/SKILL.md +369 -0
@@ -0,0 +1,13 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_shared_errors = require("../shared/errors.cjs");
3
+ //#region src/internal/asset-file-name.ts
4
+ /** Derives a file name from the asset URL path. */
5
+ function deriveAssetFileName(url) {
6
+ const candidate = (new URL(url).pathname ?? "").split("/").filter(Boolean).at(-1);
7
+ if (!candidate) throw new require_shared_errors.StoreValidationError(`Asset URL "${url}" must include a filename in the path, or set an explicit "fileName" on the asset.`);
8
+ return decodeURIComponent(candidate);
9
+ }
10
+ //#endregion
11
+ exports.deriveAssetFileName = deriveAssetFileName;
12
+
13
+ //# sourceMappingURL=asset-file-name.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-file-name.cjs","names":["StoreValidationError"],"sources":["../../src/internal/asset-file-name.ts"],"sourcesContent":["import { StoreValidationError } from \"../shared/errors.js\";\n\n/** Derives a file name from the asset URL path. */\nexport function deriveAssetFileName(url: string): string {\n const parsed = new URL(url);\n const path = parsed.pathname ?? \"\";\n const segments = path.split(\"/\").filter(Boolean);\n const candidate = segments.at(-1);\n if (!candidate) {\n throw new StoreValidationError(\n `Asset URL \"${url}\" must include a filename in the path, or set an explicit \"fileName\" on the asset.`,\n );\n }\n\n return decodeURIComponent(candidate);\n}\n"],"mappings":";;;;AAGA,SAAgB,oBAAoB,KAAqB;CAIvD,MAAM,aAFO,IADM,IAAI,IACJ,CAAC,YAAY,IACV,MAAM,IAAI,CAAC,OAAO,QACd,CAAC,GAAG,GAAG;CACjC,IAAI,CAAC,WACH,MAAM,IAAIA,sBAAAA,qBACR,cAAc,IAAI,oFACnB;CAGH,OAAO,mBAAmB,UAAU"}
@@ -0,0 +1,6 @@
1
+ //#region src/internal/asset-file-name.d.ts
2
+ /** Derives a file name from the asset URL path. */
3
+ declare function deriveAssetFileName(url: string): string;
4
+ //#endregion
5
+ export { deriveAssetFileName };
6
+ //# sourceMappingURL=asset-file-name.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-file-name.d.cts","names":[],"sources":["../../src/internal/asset-file-name.ts"],"mappings":";;iBAGgB,mBAAA,CAAoB,GAAA"}
@@ -0,0 +1,6 @@
1
+ //#region src/internal/asset-file-name.d.ts
2
+ /** Derives a file name from the asset URL path. */
3
+ declare function deriveAssetFileName(url: string): string;
4
+ //#endregion
5
+ export { deriveAssetFileName };
6
+ //# sourceMappingURL=asset-file-name.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-file-name.d.ts","names":[],"sources":["../../src/internal/asset-file-name.ts"],"mappings":";;iBAGgB,mBAAA,CAAoB,GAAA"}
@@ -0,0 +1,12 @@
1
+ import { StoreValidationError } from "../shared/errors.js";
2
+ //#region src/internal/asset-file-name.ts
3
+ /** Derives a file name from the asset URL path. */
4
+ function deriveAssetFileName(url) {
5
+ const candidate = (new URL(url).pathname ?? "").split("/").filter(Boolean).at(-1);
6
+ if (!candidate) throw new StoreValidationError(`Asset URL "${url}" must include a filename in the path, or set an explicit "fileName" on the asset.`);
7
+ return decodeURIComponent(candidate);
8
+ }
9
+ //#endregion
10
+ export { deriveAssetFileName };
11
+
12
+ //# sourceMappingURL=asset-file-name.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-file-name.js","names":[],"sources":["../../src/internal/asset-file-name.ts"],"sourcesContent":["import { StoreValidationError } from \"../shared/errors.js\";\n\n/** Derives a file name from the asset URL path. */\nexport function deriveAssetFileName(url: string): string {\n const parsed = new URL(url);\n const path = parsed.pathname ?? \"\";\n const segments = path.split(\"/\").filter(Boolean);\n const candidate = segments.at(-1);\n if (!candidate) {\n throw new StoreValidationError(\n `Asset URL \"${url}\" must include a filename in the path, or set an explicit \"fileName\" on the asset.`,\n );\n }\n\n return decodeURIComponent(candidate);\n}\n"],"mappings":";;;AAGA,SAAgB,oBAAoB,KAAqB;CAIvD,MAAM,aAFO,IADM,IAAI,IACJ,CAAC,YAAY,IACV,MAAM,IAAI,CAAC,OAAO,QACd,CAAC,GAAG,GAAG;CACjC,IAAI,CAAC,WACH,MAAM,IAAI,qBACR,cAAc,IAAI,oFACnB;CAGH,OAAO,mBAAmB,UAAU"}
@@ -0,0 +1,30 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let node_crypto = require("node:crypto");
3
+ //#region src/internal/asset-key.ts
4
+ /**
5
+ * Hash an asset key input to a fixed 16-char hex string for storage identity.
6
+ * String inputs are treated as a single segment. Array inputs are joined with
7
+ * null-byte separators to prevent ambiguity between segment boundaries.
8
+ */
9
+ function hashKey(input) {
10
+ const normalized = typeof input === "string" ? input : input.join("\0");
11
+ return (0, node_crypto.createHash)("sha256").update(normalized).digest("hex").slice(0, 16);
12
+ }
13
+ /** Produce a human-readable display key for debugging and UI. */
14
+ function displayKey(input) {
15
+ return typeof input === "string" ? input : input.join("/");
16
+ }
17
+ /**
18
+ * Validate that an asset key input is non-empty.
19
+ * Returns `true` if the input is a non-empty string or a non-empty array of non-empty strings.
20
+ */
21
+ function isValidKeyInput(input) {
22
+ if (typeof input === "string") return input.length > 0;
23
+ return input.length > 0 && input.every((s) => s.length > 0);
24
+ }
25
+ //#endregion
26
+ exports.displayKey = displayKey;
27
+ exports.hashKey = hashKey;
28
+ exports.isValidKeyInput = isValidKeyInput;
29
+
30
+ //# sourceMappingURL=asset-key.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-key.cjs","names":[],"sources":["../../src/internal/asset-key.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\n\n/** Accepted asset key input: a plain string or an array of string segments. */\nexport type AssetKeyInput = string | readonly string[];\n\n/**\n * Hash an asset key input to a fixed 16-char hex string for storage identity.\n * String inputs are treated as a single segment. Array inputs are joined with\n * null-byte separators to prevent ambiguity between segment boundaries.\n */\nexport function hashKey(input: AssetKeyInput): string {\n const normalized = typeof input === \"string\" ? input : input.join(\"\\0\");\n return createHash(\"sha256\").update(normalized).digest(\"hex\").slice(0, 16);\n}\n\n/** Produce a human-readable display key for debugging and UI. */\nexport function displayKey(input: AssetKeyInput): string {\n return typeof input === \"string\" ? input : input.join(\"/\");\n}\n\n/**\n * Validate that an asset key input is non-empty.\n * Returns `true` if the input is a non-empty string or a non-empty array of non-empty strings.\n */\nexport function isValidKeyInput(input: AssetKeyInput): boolean {\n if (typeof input === \"string\") return input.length > 0;\n return input.length > 0 && input.every((s) => s.length > 0);\n}\n"],"mappings":";;;;;;;;AAUA,SAAgB,QAAQ,OAA8B;CACpD,MAAM,aAAa,OAAO,UAAU,WAAW,QAAQ,MAAM,KAAK,KAAK;CACvE,QAAA,GAAA,YAAA,YAAkB,SAAS,CAAC,OAAO,WAAW,CAAC,OAAO,MAAM,CAAC,MAAM,GAAG,GAAG;;;AAI3E,SAAgB,WAAW,OAA8B;CACvD,OAAO,OAAO,UAAU,WAAW,QAAQ,MAAM,KAAK,IAAI;;;;;;AAO5D,SAAgB,gBAAgB,OAA+B;CAC7D,IAAI,OAAO,UAAU,UAAU,OAAO,MAAM,SAAS;CACrD,OAAO,MAAM,SAAS,KAAK,MAAM,OAAO,MAAM,EAAE,SAAS,EAAE"}
@@ -0,0 +1,19 @@
1
+ //#region src/internal/asset-key.d.ts
2
+ /** Accepted asset key input: a plain string or an array of string segments. */
3
+ type AssetKeyInput = string | readonly string[];
4
+ /**
5
+ * Hash an asset key input to a fixed 16-char hex string for storage identity.
6
+ * String inputs are treated as a single segment. Array inputs are joined with
7
+ * null-byte separators to prevent ambiguity between segment boundaries.
8
+ */
9
+ declare function hashKey(input: AssetKeyInput): string;
10
+ /** Produce a human-readable display key for debugging and UI. */
11
+ declare function displayKey(input: AssetKeyInput): string;
12
+ /**
13
+ * Validate that an asset key input is non-empty.
14
+ * Returns `true` if the input is a non-empty string or a non-empty array of non-empty strings.
15
+ */
16
+ declare function isValidKeyInput(input: AssetKeyInput): boolean;
17
+ //#endregion
18
+ export { AssetKeyInput, displayKey, hashKey, isValidKeyInput };
19
+ //# sourceMappingURL=asset-key.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-key.d.cts","names":[],"sources":["../../src/internal/asset-key.ts"],"mappings":";;KAGY,aAAA;;;;;AAOZ;iBAAgB,OAAA,CAAQ,KAAA,EAAO,aAAA;;iBAMf,UAAA,CAAW,KAAA,EAAO,aAAA;;AAAlC;;;iBAQgB,eAAA,CAAgB,KAAA,EAAO,aAAA"}
@@ -0,0 +1,19 @@
1
+ //#region src/internal/asset-key.d.ts
2
+ /** Accepted asset key input: a plain string or an array of string segments. */
3
+ type AssetKeyInput = string | readonly string[];
4
+ /**
5
+ * Hash an asset key input to a fixed 16-char hex string for storage identity.
6
+ * String inputs are treated as a single segment. Array inputs are joined with
7
+ * null-byte separators to prevent ambiguity between segment boundaries.
8
+ */
9
+ declare function hashKey(input: AssetKeyInput): string;
10
+ /** Produce a human-readable display key for debugging and UI. */
11
+ declare function displayKey(input: AssetKeyInput): string;
12
+ /**
13
+ * Validate that an asset key input is non-empty.
14
+ * Returns `true` if the input is a non-empty string or a non-empty array of non-empty strings.
15
+ */
16
+ declare function isValidKeyInput(input: AssetKeyInput): boolean;
17
+ //#endregion
18
+ export { AssetKeyInput, displayKey, hashKey, isValidKeyInput };
19
+ //# sourceMappingURL=asset-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-key.d.ts","names":[],"sources":["../../src/internal/asset-key.ts"],"mappings":";;KAGY,aAAA;;;;;AAOZ;iBAAgB,OAAA,CAAQ,KAAA,EAAO,aAAA;;iBAMf,UAAA,CAAW,KAAA,EAAO,aAAA;;AAAlC;;;iBAQgB,eAAA,CAAgB,KAAA,EAAO,aAAA"}
@@ -0,0 +1,27 @@
1
+ import { createHash } from "node:crypto";
2
+ //#region src/internal/asset-key.ts
3
+ /**
4
+ * Hash an asset key input to a fixed 16-char hex string for storage identity.
5
+ * String inputs are treated as a single segment. Array inputs are joined with
6
+ * null-byte separators to prevent ambiguity between segment boundaries.
7
+ */
8
+ function hashKey(input) {
9
+ const normalized = typeof input === "string" ? input : input.join("\0");
10
+ return createHash("sha256").update(normalized).digest("hex").slice(0, 16);
11
+ }
12
+ /** Produce a human-readable display key for debugging and UI. */
13
+ function displayKey(input) {
14
+ return typeof input === "string" ? input : input.join("/");
15
+ }
16
+ /**
17
+ * Validate that an asset key input is non-empty.
18
+ * Returns `true` if the input is a non-empty string or a non-empty array of non-empty strings.
19
+ */
20
+ function isValidKeyInput(input) {
21
+ if (typeof input === "string") return input.length > 0;
22
+ return input.length > 0 && input.every((s) => s.length > 0);
23
+ }
24
+ //#endregion
25
+ export { displayKey, hashKey, isValidKeyInput };
26
+
27
+ //# sourceMappingURL=asset-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-key.js","names":[],"sources":["../../src/internal/asset-key.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\n\n/** Accepted asset key input: a plain string or an array of string segments. */\nexport type AssetKeyInput = string | readonly string[];\n\n/**\n * Hash an asset key input to a fixed 16-char hex string for storage identity.\n * String inputs are treated as a single segment. Array inputs are joined with\n * null-byte separators to prevent ambiguity between segment boundaries.\n */\nexport function hashKey(input: AssetKeyInput): string {\n const normalized = typeof input === \"string\" ? input : input.join(\"\\0\");\n return createHash(\"sha256\").update(normalized).digest(\"hex\").slice(0, 16);\n}\n\n/** Produce a human-readable display key for debugging and UI. */\nexport function displayKey(input: AssetKeyInput): string {\n return typeof input === \"string\" ? input : input.join(\"/\");\n}\n\n/**\n * Validate that an asset key input is non-empty.\n * Returns `true` if the input is a non-empty string or a non-empty array of non-empty strings.\n */\nexport function isValidKeyInput(input: AssetKeyInput): boolean {\n if (typeof input === \"string\") return input.length > 0;\n return input.length > 0 && input.every((s) => s.length > 0);\n}\n"],"mappings":";;;;;;;AAUA,SAAgB,QAAQ,OAA8B;CACpD,MAAM,aAAa,OAAO,UAAU,WAAW,QAAQ,MAAM,KAAK,KAAK;CACvE,OAAO,WAAW,SAAS,CAAC,OAAO,WAAW,CAAC,OAAO,MAAM,CAAC,MAAM,GAAG,GAAG;;;AAI3E,SAAgB,WAAW,OAA8B;CACvD,OAAO,OAAO,UAAU,WAAW,QAAQ,MAAM,KAAK,IAAI;;;;;;AAO5D,SAAgB,gBAAgB,OAA+B;CAC7D,IAAI,OAAO,UAAU,UAAU,OAAO,MAAM,SAAS;CACrD,OAAO,MAAM,SAAS,KAAK,MAAM,OAAO,MAAM,EAAE,SAAS,EAAE"}
@@ -0,0 +1,98 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/internal/log-format.ts
3
+ const RESERVED_ENTRY_KEYS = new Set([
4
+ "timestamp",
5
+ "level",
6
+ "event",
7
+ "service",
8
+ "component"
9
+ ]);
10
+ function str(v) {
11
+ if (v === void 0 || v === null) return "unknown";
12
+ if (typeof v === "string") return v;
13
+ if (typeof v === "number" || typeof v === "boolean") return String(v);
14
+ return JSON.stringify(v);
15
+ }
16
+ function assetPath(e) {
17
+ return `${str(e.namespace)}/${str(e.item_id)}/${str(e.asset_id)}`;
18
+ }
19
+ function formatBytes(v) {
20
+ if (typeof v !== "number") return str(v);
21
+ if (v < 1024) return `${v} B`;
22
+ if (v < 1024 * 1024) return `${(v / 1024).toFixed(1)} KB`;
23
+ if (v < 1024 * 1024 * 1024) return `${(v / (1024 * 1024)).toFixed(1)} MB`;
24
+ return `${(v / (1024 * 1024 * 1024)).toFixed(1)} GB`;
25
+ }
26
+ const EVENT_MESSAGES = {
27
+ dev_passthrough_active: (e) => e.source === "option" ? "Dev passthrough enabled via config option" : `Dev passthrough enabled via NODE_ENV=${str(e.node_env)}`,
28
+ dev_passthrough_ignores_sync_failure_mode: (e) => `Dev passthrough ignores onSyncFailure "${str(e.configured_mode)}" — failures always throw in passthrough mode`,
29
+ dev_passthrough_clearing_state: (e) => `Clearing local state at ${str(e.storage_root)} (dev passthrough resets on startup)`,
30
+ cache_storage_location: (e) => `Storage location: ${str(e.storage_root)}`,
31
+ cache_initialized: (e) => {
32
+ const parts = [];
33
+ if (e.active_generation_id != null) parts.push(`generation #${str(e.active_generation_id)}`);
34
+ if (e.dev_passthrough_enabled === true) parts.push("dev passthrough on");
35
+ const suffix = parts.length > 0 ? ` (${parts.join(", ")})` : "";
36
+ return `Cache initialized at ${str(e.storage_root)}${suffix}`;
37
+ },
38
+ protocol_registered: () => "media:// protocol handler registered",
39
+ protocol_registration_skipped: (e) => `Protocol registration skipped: ${str(e.reason)}`,
40
+ protocol_request_not_found: (e) => `media:// request not found: ${assetPath(e)}`,
41
+ protocol_request_file_missing: (e) => `media:// asset file missing on disk: ${assetPath(e)}`,
42
+ protocol_request_local_resolved: (e) => {
43
+ const range = e.range ? ` range ${str(e.range)}` : "";
44
+ return `media:// serving ${assetPath(e)}${range}`;
45
+ },
46
+ ipc_attached: () => "IPC handlers attached",
47
+ ipc_attach_skipped: (e) => `IPC attach skipped: ${str(e.reason)}`,
48
+ resolve_asset_base_url_fallback: (e) => `Could not rewrite asset URL for ${str(e.context_label)}: ${str(e.error)}`,
49
+ status_snapshot_invalid: (e) => `Stored status snapshot is invalid (${str(e.error_code)}: ${str(e.error_message)}), starting fresh`,
50
+ sync_reused: (e) => `Sync already in progress (phase: ${str(e.phase)}, generation #${str(e.active_generation_id)})`,
51
+ sync_started: (e) => `Sync started (run #${str(e.run_id)})`,
52
+ manifest_resolved: (e) => `Manifest resolved: ${str(e.namespace_count)} namespace(s), ${str(e.item_count)} item(s) → generation #${str(e.staged_generation_id)} (run #${str(e.run_id)})`,
53
+ manifest_expired: (e) => e.asset_id != null ? `Manifest expired at ${str(e.expires_at)} before downloading ${assetPath(e)} (run #${str(e.run_id)})` : `Manifest expired at ${str(e.expires_at)} before downloads began (run #${str(e.run_id)})`,
54
+ sync_diffed: (e) => `Diff complete: ${str(e.total_assets)} asset(s) total, ${str(e.download_count)} to download, ${str(e.skipped_assets)} already cached (run #${str(e.run_id)})`,
55
+ asset_download_started: (e) => `Downloading ${assetPath(e)} ${str(e.resolved_version)}`,
56
+ asset_download_completed: (e) => `Downloaded ${assetPath(e)} → ${str(e.relative_path)}`,
57
+ asset_download_range_restart: (e) => `Server does not support range resume for ${assetPath(e)} (HTTP ${str(e.response_status)}), restarting full download`,
58
+ asset_download_rejected: (e) => `Download rejected for ${assetPath(e)}: HTTP ${str(e.status)} ${str(e.status_text)}`,
59
+ asset_download_retry_scheduled: (e) => `Retrying ${assetPath(e)} in ${str(e.retry_delay_ms)}ms (attempt ${str(e.attempt)})`,
60
+ asset_download_retry_exhausted: (e) => `Giving up on ${assetPath(e)} after ${str(e.attempt)} attempt(s)`,
61
+ asset_download_storage_failed: (e) => `Disk write failed for ${assetPath(e)} from ${str(e.url)}`,
62
+ generation_committed: (e) => `Generation #${str(e.active_generation_id)} committed, replacing #${str(e.previous_generation_id)} (run #${str(e.run_id)})`,
63
+ sync_completed: (e) => `Sync complete: ${str(e.downloaded_assets)} downloaded, ${str(e.skipped_assets)} skipped, ${formatBytes(e.bytes_downloaded)} transferred (run #${str(e.run_id)})`,
64
+ sync_failed: (e) => `Sync failed: ${str(e.error_code)} — ${str(e.error_message)} (run #${str(e.run_id)})`,
65
+ storage_limit_exceeded: (e) => `Storage limit exceeded: ${formatBytes(e.current_bytes)} on disk + ${formatBytes(e.estimated_download_bytes)} needed exceeds ${formatBytes(e.max_cache_bytes)} limit`,
66
+ storage_reserve_violation: (e) => `Not enough free disk space: ${formatBytes(e.available_bytes)} available, need ${formatBytes(e.estimated_download_bytes)} with ${formatBytes(e.reserve_free_bytes)} reserved`,
67
+ assets_marked_for_deletion: (e) => `Marked ${str(e.marked_count)} asset(s) from generation #${str(e.previous_generation_id)} for deletion`,
68
+ deletion_prune_skipped: () => "No expired assets to prune",
69
+ assets_pruned: (e) => `Pruned ${str(e.pruned_count)} expired asset(s) from disk`
70
+ };
71
+ function formatEnglishLine(entry) {
72
+ const messageFn = EVENT_MESSAGES[entry.event];
73
+ if (messageFn) return `[${entry.component}] ${entry.level.toUpperCase()} ${messageFn(entry)}`;
74
+ return formatGenericEnglishLine(entry);
75
+ }
76
+ function formatGenericEnglishLine(entry) {
77
+ const label = entry.event.replace(/[._]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/^./, (c) => c.toUpperCase());
78
+ const keys = Object.keys(entry).filter((k) => !RESERVED_ENTRY_KEYS.has(k));
79
+ keys.sort();
80
+ const details = keys.map((key) => {
81
+ const v = entry[key];
82
+ if (v === void 0) return null;
83
+ return `${key.replace(/[._]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase()}: ${str(v)}`;
84
+ }).filter((s) => s != null);
85
+ const suffix = details.length > 0 ? ` (${details.join(", ")})` : "";
86
+ return `[${entry.component}] ${entry.level.toUpperCase()} ${label}${suffix}`;
87
+ }
88
+ /**
89
+ * Single line for the default development console sink.
90
+ */
91
+ function formatMediaCacheConsoleLine(entry, format) {
92
+ if (format === "json") return `[${entry.component}] ${entry.level} ${entry.event} ${JSON.stringify(entry)}`;
93
+ return formatEnglishLine(entry);
94
+ }
95
+ //#endregion
96
+ exports.formatMediaCacheConsoleLine = formatMediaCacheConsoleLine;
97
+
98
+ //# sourceMappingURL=log-format.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-format.cjs","names":[],"sources":["../../src/internal/log-format.ts"],"sourcesContent":["import type { JsonValue, MediaCacheLogEvent, MediaCacheLogFormat } from \"../shared/types.js\";\n\nconst RESERVED_ENTRY_KEYS = new Set([\"timestamp\", \"level\", \"event\", \"service\", \"component\"]);\n\nfunction str(v: JsonValue | undefined): string {\n if (v === undefined || v === null) return \"unknown\";\n if (typeof v === \"string\") return v;\n if (typeof v === \"number\" || typeof v === \"boolean\") return String(v);\n return JSON.stringify(v);\n}\n\nfunction assetPath(e: MediaCacheLogEvent): string {\n return `${str(e.namespace)}/${str(e.item_id)}/${str(e.asset_id)}`;\n}\n\nfunction formatBytes(v: JsonValue | undefined): string {\n if (typeof v !== \"number\") return str(v);\n if (v < 1024) return `${v} B`;\n if (v < 1024 * 1024) return `${(v / 1024).toFixed(1)} KB`;\n if (v < 1024 * 1024 * 1024) return `${(v / (1024 * 1024)).toFixed(1)} MB`;\n return `${(v / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n}\n\ntype MessageFn = (e: MediaCacheLogEvent) => string;\n\nconst EVENT_MESSAGES: Record<string, MessageFn> = {\n dev_passthrough_active: (e) =>\n e.source === \"option\"\n ? \"Dev passthrough enabled via config option\"\n : `Dev passthrough enabled via NODE_ENV=${str(e.node_env)}`,\n\n dev_passthrough_ignores_sync_failure_mode: (e) =>\n `Dev passthrough ignores onSyncFailure \"${str(e.configured_mode)}\" — failures always throw in passthrough mode`,\n\n dev_passthrough_clearing_state: (e) =>\n `Clearing local state at ${str(e.storage_root)} (dev passthrough resets on startup)`,\n\n cache_storage_location: (e) => `Storage location: ${str(e.storage_root)}`,\n\n cache_initialized: (e) => {\n const parts: string[] = [];\n if (e.active_generation_id != null) {\n parts.push(`generation #${str(e.active_generation_id)}`);\n }\n if (e.dev_passthrough_enabled === true) {\n parts.push(\"dev passthrough on\");\n }\n const suffix = parts.length > 0 ? ` (${parts.join(\", \")})` : \"\";\n return `Cache initialized at ${str(e.storage_root)}${suffix}`;\n },\n\n protocol_registered: () => \"media:// protocol handler registered\",\n\n protocol_registration_skipped: (e) => `Protocol registration skipped: ${str(e.reason)}`,\n\n protocol_request_not_found: (e) => `media:// request not found: ${assetPath(e)}`,\n\n protocol_request_file_missing: (e) => `media:// asset file missing on disk: ${assetPath(e)}`,\n\n protocol_request_local_resolved: (e) => {\n const range = e.range ? ` range ${str(e.range)}` : \"\";\n return `media:// serving ${assetPath(e)}${range}`;\n },\n\n ipc_attached: () => \"IPC handlers attached\",\n ipc_attach_skipped: (e) => `IPC attach skipped: ${str(e.reason)}`,\n\n resolve_asset_base_url_fallback: (e) =>\n `Could not rewrite asset URL for ${str(e.context_label)}: ${str(e.error)}`,\n\n status_snapshot_invalid: (e) =>\n `Stored status snapshot is invalid (${str(e.error_code)}: ${str(e.error_message)}), starting fresh`,\n\n sync_reused: (e) =>\n `Sync already in progress (phase: ${str(e.phase)}, generation #${str(e.active_generation_id)})`,\n\n sync_started: (e) => `Sync started (run #${str(e.run_id)})`,\n\n manifest_resolved: (e) =>\n `Manifest resolved: ${str(e.namespace_count)} namespace(s), ${str(e.item_count)} item(s) → generation #${str(e.staged_generation_id)} (run #${str(e.run_id)})`,\n\n manifest_expired: (e) =>\n e.asset_id != null\n ? `Manifest expired at ${str(e.expires_at)} before downloading ${assetPath(e)} (run #${str(e.run_id)})`\n : `Manifest expired at ${str(e.expires_at)} before downloads began (run #${str(e.run_id)})`,\n\n sync_diffed: (e) =>\n `Diff complete: ${str(e.total_assets)} asset(s) total, ${str(e.download_count)} to download, ${str(e.skipped_assets)} already cached (run #${str(e.run_id)})`,\n\n asset_download_started: (e) => `Downloading ${assetPath(e)} ${str(e.resolved_version)}`,\n\n asset_download_completed: (e) => `Downloaded ${assetPath(e)} → ${str(e.relative_path)}`,\n\n asset_download_range_restart: (e) =>\n `Server does not support range resume for ${assetPath(e)} (HTTP ${str(e.response_status)}), restarting full download`,\n\n asset_download_rejected: (e) =>\n `Download rejected for ${assetPath(e)}: HTTP ${str(e.status)} ${str(e.status_text)}`,\n\n asset_download_retry_scheduled: (e) =>\n `Retrying ${assetPath(e)} in ${str(e.retry_delay_ms)}ms (attempt ${str(e.attempt)})`,\n\n asset_download_retry_exhausted: (e) =>\n `Giving up on ${assetPath(e)} after ${str(e.attempt)} attempt(s)`,\n\n asset_download_storage_failed: (e) => `Disk write failed for ${assetPath(e)} from ${str(e.url)}`,\n\n generation_committed: (e) =>\n `Generation #${str(e.active_generation_id)} committed, replacing #${str(e.previous_generation_id)} (run #${str(e.run_id)})`,\n\n sync_completed: (e) =>\n `Sync complete: ${str(e.downloaded_assets)} downloaded, ${str(e.skipped_assets)} skipped, ${formatBytes(e.bytes_downloaded)} transferred (run #${str(e.run_id)})`,\n\n sync_failed: (e) =>\n `Sync failed: ${str(e.error_code)} — ${str(e.error_message)} (run #${str(e.run_id)})`,\n\n storage_limit_exceeded: (e) =>\n `Storage limit exceeded: ${formatBytes(e.current_bytes)} on disk + ${formatBytes(e.estimated_download_bytes)} needed exceeds ${formatBytes(e.max_cache_bytes)} limit`,\n\n storage_reserve_violation: (e) =>\n `Not enough free disk space: ${formatBytes(e.available_bytes)} available, need ${formatBytes(e.estimated_download_bytes)} with ${formatBytes(e.reserve_free_bytes)} reserved`,\n\n assets_marked_for_deletion: (e) =>\n `Marked ${str(e.marked_count)} asset(s) from generation #${str(e.previous_generation_id)} for deletion`,\n\n deletion_prune_skipped: () => \"No expired assets to prune\",\n\n assets_pruned: (e) => `Pruned ${str(e.pruned_count)} expired asset(s) from disk`,\n};\n\nfunction formatEnglishLine(entry: MediaCacheLogEvent): string {\n const messageFn = EVENT_MESSAGES[entry.event];\n if (messageFn) {\n return `[${entry.component}] ${entry.level.toUpperCase()} ${messageFn(entry)}`;\n }\n return formatGenericEnglishLine(entry);\n}\n\nfunction formatGenericEnglishLine(entry: MediaCacheLogEvent): string {\n const label = entry.event\n .replace(/[._]+/g, \" \")\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/^./, (c) => c.toUpperCase());\n const keys = Object.keys(entry).filter((k) => !RESERVED_ENTRY_KEYS.has(k));\n keys.sort();\n const details = keys\n .map((key) => {\n const v = entry[key];\n if (v === undefined) return null;\n const humanKey = key\n .replace(/[._]+/g, \" \")\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .toLowerCase();\n return `${humanKey}: ${str(v)}`;\n })\n .filter((s): s is string => s != null);\n const suffix = details.length > 0 ? ` (${details.join(\", \")})` : \"\";\n return `[${entry.component}] ${entry.level.toUpperCase()} ${label}${suffix}`;\n}\n\n/**\n * Single line for the default development console sink.\n */\nexport function formatMediaCacheConsoleLine(\n entry: MediaCacheLogEvent,\n format: MediaCacheLogFormat,\n): string {\n if (format === \"json\") {\n return `[${entry.component}] ${entry.level} ${entry.event} ${JSON.stringify(entry)}`;\n }\n return formatEnglishLine(entry);\n}\n"],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { MediaCacheLogEvent, MediaCacheLogFormat } from "../shared/types.cjs";
2
+
3
+ //#region src/internal/log-format.d.ts
4
+ /**
5
+ * Single line for the default development console sink.
6
+ */
7
+ declare function formatMediaCacheConsoleLine(entry: MediaCacheLogEvent, format: MediaCacheLogFormat): string;
8
+ //#endregion
9
+ export { formatMediaCacheConsoleLine };
10
+ //# sourceMappingURL=log-format.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-format.d.cts","names":[],"sources":["../../src/internal/log-format.ts"],"mappings":";;;;;AAmKA;iBAAgB,2BAAA,CACd,KAAA,EAAO,kBAAA,EACP,MAAA,EAAQ,mBAAA"}
@@ -0,0 +1,10 @@
1
+ import { MediaCacheLogEvent, MediaCacheLogFormat } from "../shared/types.js";
2
+
3
+ //#region src/internal/log-format.d.ts
4
+ /**
5
+ * Single line for the default development console sink.
6
+ */
7
+ declare function formatMediaCacheConsoleLine(entry: MediaCacheLogEvent, format: MediaCacheLogFormat): string;
8
+ //#endregion
9
+ export { formatMediaCacheConsoleLine };
10
+ //# sourceMappingURL=log-format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-format.d.ts","names":[],"sources":["../../src/internal/log-format.ts"],"mappings":";;;;;AAmKA;iBAAgB,2BAAA,CACd,KAAA,EAAO,kBAAA,EACP,MAAA,EAAQ,mBAAA"}
@@ -0,0 +1,97 @@
1
+ //#region src/internal/log-format.ts
2
+ const RESERVED_ENTRY_KEYS = new Set([
3
+ "timestamp",
4
+ "level",
5
+ "event",
6
+ "service",
7
+ "component"
8
+ ]);
9
+ function str(v) {
10
+ if (v === void 0 || v === null) return "unknown";
11
+ if (typeof v === "string") return v;
12
+ if (typeof v === "number" || typeof v === "boolean") return String(v);
13
+ return JSON.stringify(v);
14
+ }
15
+ function assetPath(e) {
16
+ return `${str(e.namespace)}/${str(e.item_id)}/${str(e.asset_id)}`;
17
+ }
18
+ function formatBytes(v) {
19
+ if (typeof v !== "number") return str(v);
20
+ if (v < 1024) return `${v} B`;
21
+ if (v < 1024 * 1024) return `${(v / 1024).toFixed(1)} KB`;
22
+ if (v < 1024 * 1024 * 1024) return `${(v / (1024 * 1024)).toFixed(1)} MB`;
23
+ return `${(v / (1024 * 1024 * 1024)).toFixed(1)} GB`;
24
+ }
25
+ const EVENT_MESSAGES = {
26
+ dev_passthrough_active: (e) => e.source === "option" ? "Dev passthrough enabled via config option" : `Dev passthrough enabled via NODE_ENV=${str(e.node_env)}`,
27
+ dev_passthrough_ignores_sync_failure_mode: (e) => `Dev passthrough ignores onSyncFailure "${str(e.configured_mode)}" — failures always throw in passthrough mode`,
28
+ dev_passthrough_clearing_state: (e) => `Clearing local state at ${str(e.storage_root)} (dev passthrough resets on startup)`,
29
+ cache_storage_location: (e) => `Storage location: ${str(e.storage_root)}`,
30
+ cache_initialized: (e) => {
31
+ const parts = [];
32
+ if (e.active_generation_id != null) parts.push(`generation #${str(e.active_generation_id)}`);
33
+ if (e.dev_passthrough_enabled === true) parts.push("dev passthrough on");
34
+ const suffix = parts.length > 0 ? ` (${parts.join(", ")})` : "";
35
+ return `Cache initialized at ${str(e.storage_root)}${suffix}`;
36
+ },
37
+ protocol_registered: () => "media:// protocol handler registered",
38
+ protocol_registration_skipped: (e) => `Protocol registration skipped: ${str(e.reason)}`,
39
+ protocol_request_not_found: (e) => `media:// request not found: ${assetPath(e)}`,
40
+ protocol_request_file_missing: (e) => `media:// asset file missing on disk: ${assetPath(e)}`,
41
+ protocol_request_local_resolved: (e) => {
42
+ const range = e.range ? ` range ${str(e.range)}` : "";
43
+ return `media:// serving ${assetPath(e)}${range}`;
44
+ },
45
+ ipc_attached: () => "IPC handlers attached",
46
+ ipc_attach_skipped: (e) => `IPC attach skipped: ${str(e.reason)}`,
47
+ resolve_asset_base_url_fallback: (e) => `Could not rewrite asset URL for ${str(e.context_label)}: ${str(e.error)}`,
48
+ status_snapshot_invalid: (e) => `Stored status snapshot is invalid (${str(e.error_code)}: ${str(e.error_message)}), starting fresh`,
49
+ sync_reused: (e) => `Sync already in progress (phase: ${str(e.phase)}, generation #${str(e.active_generation_id)})`,
50
+ sync_started: (e) => `Sync started (run #${str(e.run_id)})`,
51
+ manifest_resolved: (e) => `Manifest resolved: ${str(e.namespace_count)} namespace(s), ${str(e.item_count)} item(s) → generation #${str(e.staged_generation_id)} (run #${str(e.run_id)})`,
52
+ manifest_expired: (e) => e.asset_id != null ? `Manifest expired at ${str(e.expires_at)} before downloading ${assetPath(e)} (run #${str(e.run_id)})` : `Manifest expired at ${str(e.expires_at)} before downloads began (run #${str(e.run_id)})`,
53
+ sync_diffed: (e) => `Diff complete: ${str(e.total_assets)} asset(s) total, ${str(e.download_count)} to download, ${str(e.skipped_assets)} already cached (run #${str(e.run_id)})`,
54
+ asset_download_started: (e) => `Downloading ${assetPath(e)} ${str(e.resolved_version)}`,
55
+ asset_download_completed: (e) => `Downloaded ${assetPath(e)} → ${str(e.relative_path)}`,
56
+ asset_download_range_restart: (e) => `Server does not support range resume for ${assetPath(e)} (HTTP ${str(e.response_status)}), restarting full download`,
57
+ asset_download_rejected: (e) => `Download rejected for ${assetPath(e)}: HTTP ${str(e.status)} ${str(e.status_text)}`,
58
+ asset_download_retry_scheduled: (e) => `Retrying ${assetPath(e)} in ${str(e.retry_delay_ms)}ms (attempt ${str(e.attempt)})`,
59
+ asset_download_retry_exhausted: (e) => `Giving up on ${assetPath(e)} after ${str(e.attempt)} attempt(s)`,
60
+ asset_download_storage_failed: (e) => `Disk write failed for ${assetPath(e)} from ${str(e.url)}`,
61
+ generation_committed: (e) => `Generation #${str(e.active_generation_id)} committed, replacing #${str(e.previous_generation_id)} (run #${str(e.run_id)})`,
62
+ sync_completed: (e) => `Sync complete: ${str(e.downloaded_assets)} downloaded, ${str(e.skipped_assets)} skipped, ${formatBytes(e.bytes_downloaded)} transferred (run #${str(e.run_id)})`,
63
+ sync_failed: (e) => `Sync failed: ${str(e.error_code)} — ${str(e.error_message)} (run #${str(e.run_id)})`,
64
+ storage_limit_exceeded: (e) => `Storage limit exceeded: ${formatBytes(e.current_bytes)} on disk + ${formatBytes(e.estimated_download_bytes)} needed exceeds ${formatBytes(e.max_cache_bytes)} limit`,
65
+ storage_reserve_violation: (e) => `Not enough free disk space: ${formatBytes(e.available_bytes)} available, need ${formatBytes(e.estimated_download_bytes)} with ${formatBytes(e.reserve_free_bytes)} reserved`,
66
+ assets_marked_for_deletion: (e) => `Marked ${str(e.marked_count)} asset(s) from generation #${str(e.previous_generation_id)} for deletion`,
67
+ deletion_prune_skipped: () => "No expired assets to prune",
68
+ assets_pruned: (e) => `Pruned ${str(e.pruned_count)} expired asset(s) from disk`
69
+ };
70
+ function formatEnglishLine(entry) {
71
+ const messageFn = EVENT_MESSAGES[entry.event];
72
+ if (messageFn) return `[${entry.component}] ${entry.level.toUpperCase()} ${messageFn(entry)}`;
73
+ return formatGenericEnglishLine(entry);
74
+ }
75
+ function formatGenericEnglishLine(entry) {
76
+ const label = entry.event.replace(/[._]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/^./, (c) => c.toUpperCase());
77
+ const keys = Object.keys(entry).filter((k) => !RESERVED_ENTRY_KEYS.has(k));
78
+ keys.sort();
79
+ const details = keys.map((key) => {
80
+ const v = entry[key];
81
+ if (v === void 0) return null;
82
+ return `${key.replace(/[._]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase()}: ${str(v)}`;
83
+ }).filter((s) => s != null);
84
+ const suffix = details.length > 0 ? ` (${details.join(", ")})` : "";
85
+ return `[${entry.component}] ${entry.level.toUpperCase()} ${label}${suffix}`;
86
+ }
87
+ /**
88
+ * Single line for the default development console sink.
89
+ */
90
+ function formatMediaCacheConsoleLine(entry, format) {
91
+ if (format === "json") return `[${entry.component}] ${entry.level} ${entry.event} ${JSON.stringify(entry)}`;
92
+ return formatEnglishLine(entry);
93
+ }
94
+ //#endregion
95
+ export { formatMediaCacheConsoleLine };
96
+
97
+ //# sourceMappingURL=log-format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-format.js","names":[],"sources":["../../src/internal/log-format.ts"],"sourcesContent":["import type { JsonValue, MediaCacheLogEvent, MediaCacheLogFormat } from \"../shared/types.js\";\n\nconst RESERVED_ENTRY_KEYS = new Set([\"timestamp\", \"level\", \"event\", \"service\", \"component\"]);\n\nfunction str(v: JsonValue | undefined): string {\n if (v === undefined || v === null) return \"unknown\";\n if (typeof v === \"string\") return v;\n if (typeof v === \"number\" || typeof v === \"boolean\") return String(v);\n return JSON.stringify(v);\n}\n\nfunction assetPath(e: MediaCacheLogEvent): string {\n return `${str(e.namespace)}/${str(e.item_id)}/${str(e.asset_id)}`;\n}\n\nfunction formatBytes(v: JsonValue | undefined): string {\n if (typeof v !== \"number\") return str(v);\n if (v < 1024) return `${v} B`;\n if (v < 1024 * 1024) return `${(v / 1024).toFixed(1)} KB`;\n if (v < 1024 * 1024 * 1024) return `${(v / (1024 * 1024)).toFixed(1)} MB`;\n return `${(v / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n}\n\ntype MessageFn = (e: MediaCacheLogEvent) => string;\n\nconst EVENT_MESSAGES: Record<string, MessageFn> = {\n dev_passthrough_active: (e) =>\n e.source === \"option\"\n ? \"Dev passthrough enabled via config option\"\n : `Dev passthrough enabled via NODE_ENV=${str(e.node_env)}`,\n\n dev_passthrough_ignores_sync_failure_mode: (e) =>\n `Dev passthrough ignores onSyncFailure \"${str(e.configured_mode)}\" — failures always throw in passthrough mode`,\n\n dev_passthrough_clearing_state: (e) =>\n `Clearing local state at ${str(e.storage_root)} (dev passthrough resets on startup)`,\n\n cache_storage_location: (e) => `Storage location: ${str(e.storage_root)}`,\n\n cache_initialized: (e) => {\n const parts: string[] = [];\n if (e.active_generation_id != null) {\n parts.push(`generation #${str(e.active_generation_id)}`);\n }\n if (e.dev_passthrough_enabled === true) {\n parts.push(\"dev passthrough on\");\n }\n const suffix = parts.length > 0 ? ` (${parts.join(\", \")})` : \"\";\n return `Cache initialized at ${str(e.storage_root)}${suffix}`;\n },\n\n protocol_registered: () => \"media:// protocol handler registered\",\n\n protocol_registration_skipped: (e) => `Protocol registration skipped: ${str(e.reason)}`,\n\n protocol_request_not_found: (e) => `media:// request not found: ${assetPath(e)}`,\n\n protocol_request_file_missing: (e) => `media:// asset file missing on disk: ${assetPath(e)}`,\n\n protocol_request_local_resolved: (e) => {\n const range = e.range ? ` range ${str(e.range)}` : \"\";\n return `media:// serving ${assetPath(e)}${range}`;\n },\n\n ipc_attached: () => \"IPC handlers attached\",\n ipc_attach_skipped: (e) => `IPC attach skipped: ${str(e.reason)}`,\n\n resolve_asset_base_url_fallback: (e) =>\n `Could not rewrite asset URL for ${str(e.context_label)}: ${str(e.error)}`,\n\n status_snapshot_invalid: (e) =>\n `Stored status snapshot is invalid (${str(e.error_code)}: ${str(e.error_message)}), starting fresh`,\n\n sync_reused: (e) =>\n `Sync already in progress (phase: ${str(e.phase)}, generation #${str(e.active_generation_id)})`,\n\n sync_started: (e) => `Sync started (run #${str(e.run_id)})`,\n\n manifest_resolved: (e) =>\n `Manifest resolved: ${str(e.namespace_count)} namespace(s), ${str(e.item_count)} item(s) → generation #${str(e.staged_generation_id)} (run #${str(e.run_id)})`,\n\n manifest_expired: (e) =>\n e.asset_id != null\n ? `Manifest expired at ${str(e.expires_at)} before downloading ${assetPath(e)} (run #${str(e.run_id)})`\n : `Manifest expired at ${str(e.expires_at)} before downloads began (run #${str(e.run_id)})`,\n\n sync_diffed: (e) =>\n `Diff complete: ${str(e.total_assets)} asset(s) total, ${str(e.download_count)} to download, ${str(e.skipped_assets)} already cached (run #${str(e.run_id)})`,\n\n asset_download_started: (e) => `Downloading ${assetPath(e)} ${str(e.resolved_version)}`,\n\n asset_download_completed: (e) => `Downloaded ${assetPath(e)} → ${str(e.relative_path)}`,\n\n asset_download_range_restart: (e) =>\n `Server does not support range resume for ${assetPath(e)} (HTTP ${str(e.response_status)}), restarting full download`,\n\n asset_download_rejected: (e) =>\n `Download rejected for ${assetPath(e)}: HTTP ${str(e.status)} ${str(e.status_text)}`,\n\n asset_download_retry_scheduled: (e) =>\n `Retrying ${assetPath(e)} in ${str(e.retry_delay_ms)}ms (attempt ${str(e.attempt)})`,\n\n asset_download_retry_exhausted: (e) =>\n `Giving up on ${assetPath(e)} after ${str(e.attempt)} attempt(s)`,\n\n asset_download_storage_failed: (e) => `Disk write failed for ${assetPath(e)} from ${str(e.url)}`,\n\n generation_committed: (e) =>\n `Generation #${str(e.active_generation_id)} committed, replacing #${str(e.previous_generation_id)} (run #${str(e.run_id)})`,\n\n sync_completed: (e) =>\n `Sync complete: ${str(e.downloaded_assets)} downloaded, ${str(e.skipped_assets)} skipped, ${formatBytes(e.bytes_downloaded)} transferred (run #${str(e.run_id)})`,\n\n sync_failed: (e) =>\n `Sync failed: ${str(e.error_code)} — ${str(e.error_message)} (run #${str(e.run_id)})`,\n\n storage_limit_exceeded: (e) =>\n `Storage limit exceeded: ${formatBytes(e.current_bytes)} on disk + ${formatBytes(e.estimated_download_bytes)} needed exceeds ${formatBytes(e.max_cache_bytes)} limit`,\n\n storage_reserve_violation: (e) =>\n `Not enough free disk space: ${formatBytes(e.available_bytes)} available, need ${formatBytes(e.estimated_download_bytes)} with ${formatBytes(e.reserve_free_bytes)} reserved`,\n\n assets_marked_for_deletion: (e) =>\n `Marked ${str(e.marked_count)} asset(s) from generation #${str(e.previous_generation_id)} for deletion`,\n\n deletion_prune_skipped: () => \"No expired assets to prune\",\n\n assets_pruned: (e) => `Pruned ${str(e.pruned_count)} expired asset(s) from disk`,\n};\n\nfunction formatEnglishLine(entry: MediaCacheLogEvent): string {\n const messageFn = EVENT_MESSAGES[entry.event];\n if (messageFn) {\n return `[${entry.component}] ${entry.level.toUpperCase()} ${messageFn(entry)}`;\n }\n return formatGenericEnglishLine(entry);\n}\n\nfunction formatGenericEnglishLine(entry: MediaCacheLogEvent): string {\n const label = entry.event\n .replace(/[._]+/g, \" \")\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/^./, (c) => c.toUpperCase());\n const keys = Object.keys(entry).filter((k) => !RESERVED_ENTRY_KEYS.has(k));\n keys.sort();\n const details = keys\n .map((key) => {\n const v = entry[key];\n if (v === undefined) return null;\n const humanKey = key\n .replace(/[._]+/g, \" \")\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .toLowerCase();\n return `${humanKey}: ${str(v)}`;\n })\n .filter((s): s is string => s != null);\n const suffix = details.length > 0 ? ` (${details.join(\", \")})` : \"\";\n return `[${entry.component}] ${entry.level.toUpperCase()} ${label}${suffix}`;\n}\n\n/**\n * Single line for the default development console sink.\n */\nexport function formatMediaCacheConsoleLine(\n entry: MediaCacheLogEvent,\n format: MediaCacheLogFormat,\n): string {\n if (format === \"json\") {\n return `[${entry.component}] ${entry.level} ${entry.event} ${JSON.stringify(entry)}`;\n }\n return formatEnglishLine(entry);\n}\n"],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/internal/media-kind.ts
3
+ const documentMimeTypes = new Set([
4
+ "application/pdf",
5
+ "application/msword",
6
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
7
+ "application/vnd.ms-excel",
8
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
9
+ "application/vnd.ms-powerpoint",
10
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
11
+ "application/rtf",
12
+ "application/epub+zip"
13
+ ]);
14
+ /**
15
+ * Derives a coarse {@link MediaKind} from a MIME type string.
16
+ *
17
+ * Mapping rules (first match wins):
18
+ * - `video/*` → `"video"`
19
+ * - `image/*` → `"image"`
20
+ * - `audio/*` → `"audio"`
21
+ * - `text/html` → `"html"`
22
+ * - `text/*` → `"text"`
23
+ * - Known document MIME types (PDF, Office, EPUB) → `"document"`
24
+ * - `application/json` → `"text"`
25
+ * - Everything else → `"binary"`
26
+ */
27
+ function mediaKindFromMime(mime) {
28
+ const normalized = mime.trim().toLowerCase().split(";")[0].trim();
29
+ const slash = normalized.indexOf("/");
30
+ if (slash === -1) return "binary";
31
+ switch (normalized.slice(0, slash)) {
32
+ case "video": return "video";
33
+ case "image": return "image";
34
+ case "audio": return "audio";
35
+ case "text": return normalized === "text/html" ? "html" : "text";
36
+ case "application":
37
+ if (documentMimeTypes.has(normalized)) return "document";
38
+ if (normalized === "application/json") return "text";
39
+ return "binary";
40
+ default: return "binary";
41
+ }
42
+ }
43
+ //#endregion
44
+ exports.mediaKindFromMime = mediaKindFromMime;
45
+
46
+ //# sourceMappingURL=media-kind.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-kind.cjs","names":[],"sources":["../../src/internal/media-kind.ts"],"sourcesContent":["import type { MediaKind } from \"../shared/types.js\";\n\nconst documentMimeTypes = new Set([\n \"application/pdf\",\n \"application/msword\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \"application/vnd.ms-excel\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n \"application/vnd.ms-powerpoint\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n \"application/rtf\",\n \"application/epub+zip\",\n]);\n\n/**\n * Derives a coarse {@link MediaKind} from a MIME type string.\n *\n * Mapping rules (first match wins):\n * - `video/*` → `\"video\"`\n * - `image/*` → `\"image\"`\n * - `audio/*` → `\"audio\"`\n * - `text/html` → `\"html\"`\n * - `text/*` → `\"text\"`\n * - Known document MIME types (PDF, Office, EPUB) → `\"document\"`\n * - `application/json` → `\"text\"`\n * - Everything else → `\"binary\"`\n */\nexport function mediaKindFromMime(mime: string): MediaKind {\n const normalized = mime.trim().toLowerCase().split(\";\")[0]!.trim();\n const slash = normalized.indexOf(\"/\");\n if (slash === -1) {\n return \"binary\";\n }\n\n const type = normalized.slice(0, slash);\n\n switch (type) {\n case \"video\":\n return \"video\";\n case \"image\":\n return \"image\";\n case \"audio\":\n return \"audio\";\n case \"text\":\n return normalized === \"text/html\" ? \"html\" : \"text\";\n case \"application\":\n if (documentMimeTypes.has(normalized)) {\n return \"document\";\n }\n if (normalized === \"application/json\") {\n return \"text\";\n }\n return \"binary\";\n default:\n return \"binary\";\n }\n}\n"],"mappings":";;AAEA,MAAM,oBAAoB,IAAI,IAAI;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;;;;;;;;;;AAeF,SAAgB,kBAAkB,MAAyB;CACzD,MAAM,aAAa,KAAK,MAAM,CAAC,aAAa,CAAC,MAAM,IAAI,CAAC,GAAI,MAAM;CAClE,MAAM,QAAQ,WAAW,QAAQ,IAAI;CACrC,IAAI,UAAU,IACZ,OAAO;CAKT,QAFa,WAAW,MAAM,GAAG,MAErB,EAAZ;EACE,KAAK,SACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,KAAK,QACH,OAAO,eAAe,cAAc,SAAS;EAC/C,KAAK;GACH,IAAI,kBAAkB,IAAI,WAAW,EACnC,OAAO;GAET,IAAI,eAAe,oBACjB,OAAO;GAET,OAAO;EACT,SACE,OAAO"}
@@ -0,0 +1,20 @@
1
+ import { MediaKind } from "../shared/types.cjs";
2
+
3
+ //#region src/internal/media-kind.d.ts
4
+ /**
5
+ * Derives a coarse {@link MediaKind} from a MIME type string.
6
+ *
7
+ * Mapping rules (first match wins):
8
+ * - `video/*` → `"video"`
9
+ * - `image/*` → `"image"`
10
+ * - `audio/*` → `"audio"`
11
+ * - `text/html` → `"html"`
12
+ * - `text/*` → `"text"`
13
+ * - Known document MIME types (PDF, Office, EPUB) → `"document"`
14
+ * - `application/json` → `"text"`
15
+ * - Everything else → `"binary"`
16
+ */
17
+ declare function mediaKindFromMime(mime: string): MediaKind;
18
+ //#endregion
19
+ export { mediaKindFromMime };
20
+ //# sourceMappingURL=media-kind.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-kind.d.cts","names":[],"sources":["../../src/internal/media-kind.ts"],"mappings":";;;;;AA2BA;;;;;;;;;;;iBAAgB,iBAAA,CAAkB,IAAA,WAAe,SAAA"}
@@ -0,0 +1,20 @@
1
+ import { MediaKind } from "../shared/types.js";
2
+
3
+ //#region src/internal/media-kind.d.ts
4
+ /**
5
+ * Derives a coarse {@link MediaKind} from a MIME type string.
6
+ *
7
+ * Mapping rules (first match wins):
8
+ * - `video/*` → `"video"`
9
+ * - `image/*` → `"image"`
10
+ * - `audio/*` → `"audio"`
11
+ * - `text/html` → `"html"`
12
+ * - `text/*` → `"text"`
13
+ * - Known document MIME types (PDF, Office, EPUB) → `"document"`
14
+ * - `application/json` → `"text"`
15
+ * - Everything else → `"binary"`
16
+ */
17
+ declare function mediaKindFromMime(mime: string): MediaKind;
18
+ //#endregion
19
+ export { mediaKindFromMime };
20
+ //# sourceMappingURL=media-kind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-kind.d.ts","names":[],"sources":["../../src/internal/media-kind.ts"],"mappings":";;;;;AA2BA;;;;;;;;;;;iBAAgB,iBAAA,CAAkB,IAAA,WAAe,SAAA"}
@@ -0,0 +1,45 @@
1
+ //#region src/internal/media-kind.ts
2
+ const documentMimeTypes = new Set([
3
+ "application/pdf",
4
+ "application/msword",
5
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
6
+ "application/vnd.ms-excel",
7
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
8
+ "application/vnd.ms-powerpoint",
9
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
10
+ "application/rtf",
11
+ "application/epub+zip"
12
+ ]);
13
+ /**
14
+ * Derives a coarse {@link MediaKind} from a MIME type string.
15
+ *
16
+ * Mapping rules (first match wins):
17
+ * - `video/*` → `"video"`
18
+ * - `image/*` → `"image"`
19
+ * - `audio/*` → `"audio"`
20
+ * - `text/html` → `"html"`
21
+ * - `text/*` → `"text"`
22
+ * - Known document MIME types (PDF, Office, EPUB) → `"document"`
23
+ * - `application/json` → `"text"`
24
+ * - Everything else → `"binary"`
25
+ */
26
+ function mediaKindFromMime(mime) {
27
+ const normalized = mime.trim().toLowerCase().split(";")[0].trim();
28
+ const slash = normalized.indexOf("/");
29
+ if (slash === -1) return "binary";
30
+ switch (normalized.slice(0, slash)) {
31
+ case "video": return "video";
32
+ case "image": return "image";
33
+ case "audio": return "audio";
34
+ case "text": return normalized === "text/html" ? "html" : "text";
35
+ case "application":
36
+ if (documentMimeTypes.has(normalized)) return "document";
37
+ if (normalized === "application/json") return "text";
38
+ return "binary";
39
+ default: return "binary";
40
+ }
41
+ }
42
+ //#endregion
43
+ export { mediaKindFromMime };
44
+
45
+ //# sourceMappingURL=media-kind.js.map