@ai-matrx/media 0.8.0 → 0.9.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 (185) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/files/engine/api/assets.d.ts +223 -0
  3. package/dist/files/engine/api/assets.js +124 -0
  4. package/dist/files/engine/api/assets.js.map +1 -0
  5. package/dist/files/engine/api/direct.d.ts +43 -0
  6. package/dist/files/engine/api/direct.js +73 -0
  7. package/dist/files/engine/api/direct.js.map +1 -0
  8. package/dist/files/engine/api/fileOrganization.d.ts +34 -0
  9. package/dist/files/engine/api/fileOrganization.js +38 -0
  10. package/dist/files/engine/api/fileOrganization.js.map +1 -0
  11. package/dist/files/engine/api/files.d.ts +249 -0
  12. package/dist/files/engine/api/files.js +231 -0
  13. package/dist/files/engine/api/files.js.map +1 -0
  14. package/dist/files/engine/api/folders.d.ts +63 -0
  15. package/dist/files/engine/api/folders.js +56 -0
  16. package/dist/files/engine/api/folders.js.map +1 -0
  17. package/dist/files/engine/api/office.d.ts +27 -0
  18. package/dist/files/engine/api/office.js +19 -0
  19. package/dist/files/engine/api/office.js.map +1 -0
  20. package/dist/files/engine/api/permissions.d.ts +37 -0
  21. package/dist/files/engine/api/permissions.js +109 -0
  22. package/dist/files/engine/api/permissions.js.map +1 -0
  23. package/dist/files/engine/api/versions.d.ts +26 -0
  24. package/dist/files/engine/api/versions.js +37 -0
  25. package/dist/files/engine/api/versions.js.map +1 -0
  26. package/dist/files/engine/cache/idb-store.d.ts +95 -0
  27. package/dist/files/engine/cache/idb-store.js +172 -0
  28. package/dist/files/engine/cache/idb-store.js.map +1 -0
  29. package/dist/files/engine/cache/policy.d.ts +14 -0
  30. package/dist/files/engine/cache/policy.js +40 -0
  31. package/dist/files/engine/cache/policy.js.map +1 -0
  32. package/dist/files/engine/cache/register-service-worker.d.ts +57 -0
  33. package/dist/files/engine/cache/register-service-worker.js +80 -0
  34. package/dist/files/engine/cache/register-service-worker.js.map +1 -0
  35. package/dist/files/engine/db-types.d.ts +48865 -0
  36. package/dist/files/engine/db-types.js +1 -0
  37. package/dist/files/engine/db-types.js.map +1 -0
  38. package/dist/files/engine/filesDb.d.ts +1913 -0
  39. package/dist/files/engine/filesDb.js +28 -0
  40. package/dist/files/engine/filesDb.js.map +1 -0
  41. package/dist/files/engine/handler/handler.d.ts +82 -0
  42. package/dist/files/engine/handler/handler.js +124 -0
  43. package/dist/files/engine/handler/handler.js.map +1 -0
  44. package/dist/files/engine/handler/hooks/useFile.d.ts +17 -0
  45. package/dist/files/engine/handler/hooks/useFile.js +75 -0
  46. package/dist/files/engine/handler/hooks/useFile.js.map +1 -0
  47. package/dist/files/engine/handler/hooks/useFileUpload.d.ts +76 -0
  48. package/dist/files/engine/handler/hooks/useFileUpload.js +67 -0
  49. package/dist/files/engine/handler/hooks/useFileUpload.js.map +1 -0
  50. package/dist/files/engine/handler/input/normalize.d.ts +14 -0
  51. package/dist/files/engine/handler/input/normalize.js +365 -0
  52. package/dist/files/engine/handler/input/normalize.js.map +1 -0
  53. package/dist/files/engine/handler/intelligence/access.d.ts +35 -0
  54. package/dist/files/engine/handler/intelligence/access.js +85 -0
  55. package/dist/files/engine/handler/intelligence/access.js.map +1 -0
  56. package/dist/files/engine/handler/intelligence/magic-bytes.d.ts +21 -0
  57. package/dist/files/engine/handler/intelligence/magic-bytes.js +67 -0
  58. package/dist/files/engine/handler/intelligence/magic-bytes.js.map +1 -0
  59. package/dist/files/engine/handler/output/target.d.ts +19 -0
  60. package/dist/files/engine/handler/output/target.js +222 -0
  61. package/dist/files/engine/handler/output/target.js.map +1 -0
  62. package/dist/files/engine/handler/resolver.d.ts +34 -0
  63. package/dist/files/engine/handler/resolver.js +133 -0
  64. package/dist/files/engine/handler/resolver.js.map +1 -0
  65. package/dist/files/engine/handler/types.d.ts +367 -0
  66. package/dist/files/engine/handler/types.js +1 -0
  67. package/dist/files/engine/handler/types.js.map +1 -0
  68. package/dist/files/engine/handler/upload.d.ts +32 -0
  69. package/dist/files/engine/handler/upload.js +295 -0
  70. package/dist/files/engine/handler/upload.js.map +1 -0
  71. package/dist/files/engine/handler/utils/classify.d.ts +14 -0
  72. package/dist/files/engine/handler/utils/classify.js +27 -0
  73. package/dist/files/engine/handler/utils/classify.js.map +1 -0
  74. package/dist/files/engine/handler/utils/prefer-locator.d.ts +32 -0
  75. package/dist/files/engine/handler/utils/prefer-locator.js +34 -0
  76. package/dist/files/engine/handler/utils/prefer-locator.js.map +1 -0
  77. package/dist/files/engine/handler/utils/python-base.d.ts +129 -0
  78. package/dist/files/engine/handler/utils/python-base.js +60 -0
  79. package/dist/files/engine/handler/utils/python-base.js.map +1 -0
  80. package/dist/files/engine/hooks/blob-cache.d.ts +130 -0
  81. package/dist/files/engine/hooks/blob-cache.js +162 -0
  82. package/dist/files/engine/hooks/blob-cache.js.map +1 -0
  83. package/dist/files/engine/hooks/office-extraction-cache.d.ts +28 -0
  84. package/dist/files/engine/hooks/office-extraction-cache.js +67 -0
  85. package/dist/files/engine/hooks/office-extraction-cache.js.map +1 -0
  86. package/dist/files/engine/host/configure.d.ts +166 -0
  87. package/dist/files/engine/host/configure.js +30 -0
  88. package/dist/files/engine/host/configure.js.map +1 -0
  89. package/dist/files/engine/host/org.d.ts +8 -0
  90. package/dist/files/engine/host/org.js +16 -0
  91. package/dist/files/engine/host/org.js.map +1 -0
  92. package/dist/files/engine/host/python-client.d.ts +60 -0
  93. package/dist/files/engine/host/python-client.js +46 -0
  94. package/dist/files/engine/host/python-client.js.map +1 -0
  95. package/dist/files/engine/host/share-links.d.ts +20 -0
  96. package/dist/files/engine/host/share-links.js +32 -0
  97. package/dist/files/engine/host/share-links.js.map +1 -0
  98. package/dist/files/engine/host/store.d.ts +24 -0
  99. package/dist/files/engine/host/store.js +23 -0
  100. package/dist/files/engine/host/store.js.map +1 -0
  101. package/dist/files/engine/host/supabase.d.ts +3808 -0
  102. package/dist/files/engine/host/supabase.js +33 -0
  103. package/dist/files/engine/host/supabase.js.map +1 -0
  104. package/dist/files/engine/host/toast.d.ts +14 -0
  105. package/dist/files/engine/host/toast.js +20 -0
  106. package/dist/files/engine/host/toast.js.map +1 -0
  107. package/dist/files/engine/host/typed-client.d.ts +136 -0
  108. package/dist/files/engine/host/typed-client.js +66 -0
  109. package/dist/files/engine/host/typed-client.js.map +1 -0
  110. package/dist/files/engine/index.d.ts +22 -0
  111. package/dist/files/engine/index.js +49 -0
  112. package/dist/files/engine/index.js.map +1 -0
  113. package/dist/files/engine/media/our-file-sources.d.ts +39 -0
  114. package/dist/files/engine/media/our-file-sources.js +83 -0
  115. package/dist/files/engine/media/our-file-sources.js.map +1 -0
  116. package/dist/files/engine/media/signed-url.d.ts +1 -0
  117. package/dist/files/engine/media/signed-url.js +6 -0
  118. package/dist/files/engine/media/signed-url.js.map +1 -0
  119. package/dist/files/engine/redux/converters.d.ts +73 -0
  120. package/dist/files/engine/redux/converters.js +286 -0
  121. package/dist/files/engine/redux/converters.js.map +1 -0
  122. package/dist/files/engine/redux/file-hydration.d.ts +15 -0
  123. package/dist/files/engine/redux/file-hydration.js +46 -0
  124. package/dist/files/engine/redux/file-hydration.js.map +1 -0
  125. package/dist/files/engine/redux/file-tree-auth-boundary.d.ts +5 -0
  126. package/dist/files/engine/redux/file-tree-auth-boundary.js +28 -0
  127. package/dist/files/engine/redux/file-tree-auth-boundary.js.map +1 -0
  128. package/dist/files/engine/redux/file-tree-timeout.d.ts +32 -0
  129. package/dist/files/engine/redux/file-tree-timeout.js +73 -0
  130. package/dist/files/engine/redux/file-tree-timeout.js.map +1 -0
  131. package/dist/files/engine/redux/mutation-toast-middleware.d.ts +27 -0
  132. package/dist/files/engine/redux/mutation-toast-middleware.js +103 -0
  133. package/dist/files/engine/redux/mutation-toast-middleware.js.map +1 -0
  134. package/dist/files/engine/redux/realtime-middleware.d.ts +61 -0
  135. package/dist/files/engine/redux/realtime-middleware.js +431 -0
  136. package/dist/files/engine/redux/realtime-middleware.js.map +1 -0
  137. package/dist/files/engine/redux/request-ledger.d.ts +68 -0
  138. package/dist/files/engine/redux/request-ledger.js +66 -0
  139. package/dist/files/engine/redux/request-ledger.js.map +1 -0
  140. package/dist/files/engine/redux/selectors.d.ts +3254 -0
  141. package/dist/files/engine/redux/selectors.js +428 -0
  142. package/dist/files/engine/redux/selectors.js.map +1 -0
  143. package/dist/files/engine/redux/slice.d.ts +157 -0
  144. package/dist/files/engine/redux/slice.js +836 -0
  145. package/dist/files/engine/redux/slice.js.map +1 -0
  146. package/dist/files/engine/redux/thunks.d.ts +449 -0
  147. package/dist/files/engine/redux/thunks.js +1684 -0
  148. package/dist/files/engine/redux/thunks.js.map +1 -0
  149. package/dist/files/engine/redux/tree-utils.d.ts +90 -0
  150. package/dist/files/engine/redux/tree-utils.js +200 -0
  151. package/dist/files/engine/redux/tree-utils.js.map +1 -0
  152. package/dist/files/engine/support/claimsUser.d.ts +77 -0
  153. package/dist/files/engine/support/claimsUser.js +48 -0
  154. package/dist/files/engine/support/claimsUser.js.map +1 -0
  155. package/dist/files/engine/support/datetime.d.ts +6 -0
  156. package/dist/files/engine/support/datetime.js +15 -0
  157. package/dist/files/engine/support/datetime.js.map +1 -0
  158. package/dist/files/engine/support/document-visibility.d.ts +14 -0
  159. package/dist/files/engine/support/document-visibility.js +28 -0
  160. package/dist/files/engine/support/document-visibility.js.map +1 -0
  161. package/dist/files/engine/support/logger.d.ts +28 -0
  162. package/dist/files/engine/support/logger.js +36 -0
  163. package/dist/files/engine/support/logger.js.map +1 -0
  164. package/dist/files/engine/types.d.ts +1081 -0
  165. package/dist/files/engine/types.js +30 -0
  166. package/dist/files/engine/types.js.map +1 -0
  167. package/dist/files/engine/upload/cloudUpload.d.ts +182 -0
  168. package/dist/files/engine/upload/cloudUpload.js +418 -0
  169. package/dist/files/engine/upload/cloudUpload.js.map +1 -0
  170. package/dist/files/engine/upload/tusUpload.d.ts +100 -0
  171. package/dist/files/engine/upload/tusUpload.js +258 -0
  172. package/dist/files/engine/upload/tusUpload.js.map +1 -0
  173. package/dist/files/engine/upload/uploadDedupGuard.d.ts +58 -0
  174. package/dist/files/engine/upload/uploadDedupGuard.js +41 -0
  175. package/dist/files/engine/upload/uploadDedupGuard.js.map +1 -0
  176. package/dist/files/engine/upload/uploadGuardOpeners.d.ts +70 -0
  177. package/dist/files/engine/upload/uploadGuardOpeners.js +54 -0
  178. package/dist/files/engine/upload/uploadGuardOpeners.js.map +1 -0
  179. package/dist/files/engine/utils/file-types.d.ts +243 -0
  180. package/dist/files/engine/utils/file-types.js +1722 -0
  181. package/dist/files/engine/utils/file-types.js.map +1 -0
  182. package/dist/files/engine/utils/user-visible.d.ts +133 -0
  183. package/dist/files/engine/utils/user-visible.js +115 -0
  184. package/dist/files/engine/utils/user-visible.js.map +1 -0
  185. package/package.json +393 -9
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/files/engine/cache/policy.ts"],"sourcesContent":["/**\n * features/files/cache/policy.ts\n *\n * Per-MIME size policy for the IndexedDB tier. The in-memory LRU caches\n * everything (it's session-scoped and bounded by total bytes); IDB only\n * persists what's worth re-loading across page reloads.\n *\n * The defaults are conservative: cache the large, expensive-to-re-fetch\n * artifacts (PDFs, video posters, audio) and the small text-y assets\n * (markdown, JSON, code) that previewers consult repeatedly.\n *\n * Returned `false` means \"do not write to IDB\". Memory LRU still caches.\n */\n\ninterface MimePolicy {\n /** Match the entire mime prefix (e.g. `image/`, `application/`). */\n prefix?: string;\n /** Exact mime types to match (highest precedence). */\n exact?: string[];\n /** Max bytes per entry; oversize files skip IDB. */\n maxBytes: number;\n}\n\nconst POLICIES: MimePolicy[] = [\n { prefix: \"image/\", maxBytes: 50 * 1024 * 1024 },\n { prefix: \"audio/\", maxBytes: 100 * 1024 * 1024 },\n // Videos cache only up to 50 MB by default. Larger videos rely on\n // native HTML5 streaming + server-side Range responses.\n { prefix: \"video/\", maxBytes: 50 * 1024 * 1024 },\n { exact: [\"application/pdf\"], maxBytes: 250 * 1024 * 1024 },\n {\n exact: [\n \"application/zip\",\n \"application/x-zip-compressed\",\n \"application/x-tar\",\n \"application/gzip\",\n ],\n maxBytes: 500 * 1024 * 1024,\n },\n {\n prefix: \"text/\",\n maxBytes: 10 * 1024 * 1024,\n },\n { exact: [\"application/json\", \"application/xml\"], maxBytes: 10 * 1024 * 1024 },\n];\n\nconst FALLBACK_MAX_BYTES = 25 * 1024 * 1024;\n\nexport function shouldPersistInIdb(\n mimeType: string | null | undefined,\n byteSize: number,\n): boolean {\n if (!mimeType || byteSize <= 0) return false;\n const normalized = mimeType.toLowerCase();\n for (const policy of POLICIES) {\n if (policy.exact?.includes(normalized)) {\n return byteSize <= policy.maxBytes;\n }\n if (policy.prefix && normalized.startsWith(policy.prefix)) {\n return byteSize <= policy.maxBytes;\n }\n }\n return byteSize <= FALLBACK_MAX_BYTES;\n}\n"],"mappings":"AAuBA,MAAM,WAAyB;AAAA,EAC7B,EAAE,QAAQ,UAAU,UAAU,KAAK,OAAO,KAAK;AAAA,EAC/C,EAAE,QAAQ,UAAU,UAAU,MAAM,OAAO,KAAK;AAAA;AAAA;AAAA,EAGhD,EAAE,QAAQ,UAAU,UAAU,KAAK,OAAO,KAAK;AAAA,EAC/C,EAAE,OAAO,CAAC,iBAAiB,GAAG,UAAU,MAAM,OAAO,KAAK;AAAA,EAC1D;AAAA,IACE,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU,MAAM,OAAO;AAAA,EACzB;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,UAAU,KAAK,OAAO;AAAA,EACxB;AAAA,EACA,EAAE,OAAO,CAAC,oBAAoB,iBAAiB,GAAG,UAAU,KAAK,OAAO,KAAK;AAC/E;AAEA,MAAM,qBAAqB,KAAK,OAAO;AAEhC,SAAS,mBACd,UACA,UACS;AACT,MAAI,CAAC,YAAY,YAAY,EAAG,QAAO;AACvC,QAAM,aAAa,SAAS,YAAY;AACxC,aAAW,UAAU,UAAU;AAC7B,QAAI,OAAO,OAAO,SAAS,UAAU,GAAG;AACtC,aAAO,YAAY,OAAO;AAAA,IAC5B;AACA,QAAI,OAAO,UAAU,WAAW,WAAW,OAAO,MAAM,GAAG;AACzD,aAAO,YAAY,OAAO;AAAA,IAC5B;AAAA,EACF;AACA,SAAO,YAAY;AACrB;","names":[]}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * features/files/cache/register-service-worker.ts
3
+ *
4
+ * Register the blob-cache Service Worker (`/blob-sw.js`) and push the
5
+ * current backend URL + signed-in user id into it. The SW intercepts
6
+ * cloud-files byte fetches (and registered CDN / share-link URLs) and
7
+ * serves them from IndexedDB when present, falling through to the
8
+ * network otherwise.
9
+ *
10
+ * Called from `app/DeferredSingletons.tsx` (a Client Component) on idle
11
+ * after auth boot, so SSR is unaffected and registration doesn't block
12
+ * the first paint.
13
+ *
14
+ * Dev-mode guards:
15
+ * - Disabled by default in development (`NODE_ENV !== 'production'`)
16
+ * to avoid HMR interference with Next's RSC cache.
17
+ * - Opt-in via `localStorage.matrx_dev_sw = '1'` for local testing.
18
+ *
19
+ * iOS Safari / private-browsing failure modes are tolerated silently —
20
+ * if `navigator.serviceWorker` is undefined or `register()` rejects,
21
+ * the app continues to function with just the in-memory LRU + IDB tiers
22
+ * (no transparent `<img src>` interception).
23
+ */
24
+ /**
25
+ * Register the SW and (when ready) send the initial `set-config` message
26
+ * with the backend URL and signed-in user id. Returns the registration
27
+ * (or null when SW isn't supported / registration failed).
28
+ *
29
+ * Idempotent — subsequent calls reuse the in-flight promise.
30
+ */
31
+ export declare function registerBlobCacheServiceWorker(args: {
32
+ backendUrl: string;
33
+ userId: string | null;
34
+ /** When true, force-register even in dev. */
35
+ force?: boolean;
36
+ }): Promise<ServiceWorkerRegistration | null>;
37
+ /**
38
+ * Imperative invalidation. Drops every cached version of a fileId in the
39
+ * SW's IDB tier. Called from invalidate() in features/files/hooks/blob-cache.ts.
40
+ */
41
+ export declare function postBlobCacheInvalidate(fileId: string): Promise<void>;
42
+ /**
43
+ * Per-user wipe. Called from sign-out.
44
+ */
45
+ export declare function postBlobCacheClearUser(userId: string): Promise<void>;
46
+ /**
47
+ * Register a (canonical-URL → fileId+version+checksum) mapping so the SW
48
+ * can recognize a public CDN URL or other byte URL the page has issued
49
+ * and serve it from the same cache entry as the canonical
50
+ * `/files/{id}/download` URL.
51
+ */
52
+ export declare function postBlobCacheRegisterUrlMapping(args: {
53
+ url: string;
54
+ fileId: string;
55
+ version: number | null;
56
+ checksum: string | null;
57
+ }): Promise<void>;
@@ -0,0 +1,80 @@
1
+ const SW_URL = "/blob-sw.js";
2
+ let registrationPromise = null;
3
+ function registerBlobCacheServiceWorker(args) {
4
+ if (registrationPromise) {
5
+ void postSetConfig(args).catch(() => void 0);
6
+ return registrationPromise;
7
+ }
8
+ registrationPromise = (async () => {
9
+ if (typeof window === "undefined" || !("serviceWorker" in navigator)) {
10
+ return null;
11
+ }
12
+ const isProd = false;
13
+ const devOptIn = typeof window !== "undefined" && window.localStorage?.getItem("matrx_dev_sw") === "1";
14
+ if (!isProd && !devOptIn && !args.force) {
15
+ return null;
16
+ }
17
+ try {
18
+ const reg = await navigator.serviceWorker.register(SW_URL, {
19
+ scope: "/"
20
+ });
21
+ void postSetConfig(args);
22
+ navigator.serviceWorker.addEventListener("controllerchange", () => {
23
+ void postSetConfig(args);
24
+ });
25
+ return reg;
26
+ } catch (err) {
27
+ console.warn("[blob-cache-sw] registration failed", err);
28
+ return null;
29
+ }
30
+ })();
31
+ return registrationPromise;
32
+ }
33
+ async function postSetConfig(args) {
34
+ const target = navigator.serviceWorker.controller ?? await navigator.serviceWorker.ready.then((r) => r.active);
35
+ if (!target) return;
36
+ const filesUrl = process.env.NEXT_PUBLIC_FILES_URL || void 0;
37
+ target.postMessage({
38
+ kind: "set-config",
39
+ backendUrl: args.backendUrl.replace(/\/$/, ""),
40
+ filesUrl: filesUrl ? filesUrl.replace(/\/$/, "") : void 0,
41
+ userId: args.userId
42
+ });
43
+ }
44
+ async function postBlobCacheInvalidate(fileId) {
45
+ if (typeof navigator === "undefined" || !("serviceWorker" in navigator)) {
46
+ return;
47
+ }
48
+ const ctrl = navigator.serviceWorker.controller;
49
+ if (!ctrl) return;
50
+ ctrl.postMessage({ kind: "invalidate", fileId });
51
+ }
52
+ async function postBlobCacheClearUser(userId) {
53
+ if (typeof navigator === "undefined" || !("serviceWorker" in navigator)) {
54
+ return;
55
+ }
56
+ const ctrl = navigator.serviceWorker.controller;
57
+ if (!ctrl) return;
58
+ ctrl.postMessage({ kind: "clear-user", userId });
59
+ }
60
+ async function postBlobCacheRegisterUrlMapping(args) {
61
+ if (typeof navigator === "undefined" || !("serviceWorker" in navigator)) {
62
+ return;
63
+ }
64
+ const ctrl = navigator.serviceWorker.controller;
65
+ if (!ctrl) return;
66
+ ctrl.postMessage({
67
+ kind: "register-url-mapping",
68
+ url: args.url,
69
+ fileId: args.fileId,
70
+ version: args.version,
71
+ checksum: args.checksum
72
+ });
73
+ }
74
+ export {
75
+ postBlobCacheClearUser,
76
+ postBlobCacheInvalidate,
77
+ postBlobCacheRegisterUrlMapping,
78
+ registerBlobCacheServiceWorker
79
+ };
80
+ //# sourceMappingURL=register-service-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/files/engine/cache/register-service-worker.ts"],"sourcesContent":["/**\n * features/files/cache/register-service-worker.ts\n *\n * Register the blob-cache Service Worker (`/blob-sw.js`) and push the\n * current backend URL + signed-in user id into it. The SW intercepts\n * cloud-files byte fetches (and registered CDN / share-link URLs) and\n * serves them from IndexedDB when present, falling through to the\n * network otherwise.\n *\n * Called from `app/DeferredSingletons.tsx` (a Client Component) on idle\n * after auth boot, so SSR is unaffected and registration doesn't block\n * the first paint.\n *\n * Dev-mode guards:\n * - Disabled by default in development (`NODE_ENV !== 'production'`)\n * to avoid HMR interference with Next's RSC cache.\n * - Opt-in via `localStorage.matrx_dev_sw = '1'` for local testing.\n *\n * iOS Safari / private-browsing failure modes are tolerated silently —\n * if `navigator.serviceWorker` is undefined or `register()` rejects,\n * the app continues to function with just the in-memory LRU + IDB tiers\n * (no transparent `<img src>` interception).\n */\n\nconst SW_URL = \"/blob-sw.js\";\n\nlet registrationPromise: Promise<ServiceWorkerRegistration | null> | null = null;\n\n/**\n * Register the SW and (when ready) send the initial `set-config` message\n * with the backend URL and signed-in user id. Returns the registration\n * (or null when SW isn't supported / registration failed).\n *\n * Idempotent — subsequent calls reuse the in-flight promise.\n */\nexport function registerBlobCacheServiceWorker(args: {\n backendUrl: string;\n userId: string | null;\n /** When true, force-register even in dev. */\n force?: boolean;\n}): Promise<ServiceWorkerRegistration | null> {\n if (registrationPromise) {\n void postSetConfig(args).catch(() => undefined);\n return registrationPromise;\n }\n registrationPromise = (async () => {\n if (typeof window === \"undefined\" || !(\"serviceWorker\" in navigator)) {\n return null;\n }\n const isProd = process.env.NODE_ENV === \"production\";\n const devOptIn =\n typeof window !== \"undefined\" &&\n window.localStorage?.getItem(\"matrx_dev_sw\") === \"1\";\n if (!isProd && !devOptIn && !args.force) {\n return null;\n }\n try {\n const reg = await navigator.serviceWorker.register(SW_URL, {\n scope: \"/\",\n });\n // Push config as soon as we have a controller — covers fresh\n // registrations (where the controller may not be set yet) by also\n // listening on `controllerchange`.\n void postSetConfig(args);\n navigator.serviceWorker.addEventListener(\"controllerchange\", () => {\n void postSetConfig(args);\n });\n return reg;\n } catch (err) {\n // eslint-disable-next-line no-console\n console.warn(\"[blob-cache-sw] registration failed\", err);\n return null;\n }\n })();\n return registrationPromise;\n}\n\nasync function postSetConfig(args: {\n backendUrl: string;\n userId: string | null;\n}): Promise<void> {\n const target =\n navigator.serviceWorker.controller ??\n (await navigator.serviceWorker.ready.then((r) => r.active));\n if (!target) return;\n // NEXT_PUBLIC_FILES_URL: when set, file/share downloads go to the standalone\n // matrx-files service; tell the SW so it caches those the same as backend\n // downloads. Read from env here so no call site needs to thread it through.\n const filesUrl = (process.env.NEXT_PUBLIC_FILES_URL as string | undefined) || undefined;\n target.postMessage({\n kind: \"set-config\",\n backendUrl: args.backendUrl.replace(/\\/$/, \"\"),\n filesUrl: filesUrl ? filesUrl.replace(/\\/$/, \"\") : undefined,\n userId: args.userId,\n });\n}\n\n/**\n * Imperative invalidation. Drops every cached version of a fileId in the\n * SW's IDB tier. Called from invalidate() in features/files/hooks/blob-cache.ts.\n */\nexport async function postBlobCacheInvalidate(fileId: string): Promise<void> {\n if (typeof navigator === \"undefined\" || !(\"serviceWorker\" in navigator)) {\n return;\n }\n const ctrl = navigator.serviceWorker.controller;\n if (!ctrl) return;\n ctrl.postMessage({ kind: \"invalidate\", fileId });\n}\n\n/**\n * Per-user wipe. Called from sign-out.\n */\nexport async function postBlobCacheClearUser(userId: string): Promise<void> {\n if (typeof navigator === \"undefined\" || !(\"serviceWorker\" in navigator)) {\n return;\n }\n const ctrl = navigator.serviceWorker.controller;\n if (!ctrl) return;\n ctrl.postMessage({ kind: \"clear-user\", userId });\n}\n\n/**\n * Register a (canonical-URL → fileId+version+checksum) mapping so the SW\n * can recognize a public CDN URL or other byte URL the page has issued\n * and serve it from the same cache entry as the canonical\n * `/files/{id}/download` URL.\n */\nexport async function postBlobCacheRegisterUrlMapping(args: {\n url: string;\n fileId: string;\n version: number | null;\n checksum: string | null;\n}): Promise<void> {\n if (typeof navigator === \"undefined\" || !(\"serviceWorker\" in navigator)) {\n return;\n }\n const ctrl = navigator.serviceWorker.controller;\n if (!ctrl) return;\n ctrl.postMessage({\n kind: \"register-url-mapping\",\n url: args.url,\n fileId: args.fileId,\n version: args.version,\n checksum: args.checksum,\n });\n}\n"],"mappings":"AAwBA,MAAM,SAAS;AAEf,IAAI,sBAAwE;AASrE,SAAS,+BAA+B,MAKD;AAC5C,MAAI,qBAAqB;AACvB,SAAK,cAAc,IAAI,EAAE,MAAM,MAAM,MAAS;AAC9C,WAAO;AAAA,EACT;AACA,yBAAuB,YAAY;AACjC,QAAI,OAAO,WAAW,eAAe,EAAE,mBAAmB,YAAY;AACpE,aAAO;AAAA,IACT;AACA,UAAM,SAAS;AACf,UAAM,WACJ,OAAO,WAAW,eAClB,OAAO,cAAc,QAAQ,cAAc,MAAM;AACnD,QAAI,CAAC,UAAU,CAAC,YAAY,CAAC,KAAK,OAAO;AACvC,aAAO;AAAA,IACT;AACA,QAAI;AACF,YAAM,MAAM,MAAM,UAAU,cAAc,SAAS,QAAQ;AAAA,QACzD,OAAO;AAAA,MACT,CAAC;AAID,WAAK,cAAc,IAAI;AACvB,gBAAU,cAAc,iBAAiB,oBAAoB,MAAM;AACjE,aAAK,cAAc,IAAI;AAAA,MACzB,CAAC;AACD,aAAO;AAAA,IACT,SAAS,KAAK;AAEZ,cAAQ,KAAK,uCAAuC,GAAG;AACvD,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AACH,SAAO;AACT;AAEA,eAAe,cAAc,MAGX;AAChB,QAAM,SACJ,UAAU,cAAc,cACvB,MAAM,UAAU,cAAc,MAAM,KAAK,CAAC,MAAM,EAAE,MAAM;AAC3D,MAAI,CAAC,OAAQ;AAIb,QAAM,WAAY,QAAQ,IAAI,yBAAgD;AAC9E,SAAO,YAAY;AAAA,IACjB,MAAM;AAAA,IACN,YAAY,KAAK,WAAW,QAAQ,OAAO,EAAE;AAAA,IAC7C,UAAU,WAAW,SAAS,QAAQ,OAAO,EAAE,IAAI;AAAA,IACnD,QAAQ,KAAK;AAAA,EACf,CAAC;AACH;AAMA,eAAsB,wBAAwB,QAA+B;AAC3E,MAAI,OAAO,cAAc,eAAe,EAAE,mBAAmB,YAAY;AACvE;AAAA,EACF;AACA,QAAM,OAAO,UAAU,cAAc;AACrC,MAAI,CAAC,KAAM;AACX,OAAK,YAAY,EAAE,MAAM,cAAc,OAAO,CAAC;AACjD;AAKA,eAAsB,uBAAuB,QAA+B;AAC1E,MAAI,OAAO,cAAc,eAAe,EAAE,mBAAmB,YAAY;AACvE;AAAA,EACF;AACA,QAAM,OAAO,UAAU,cAAc;AACrC,MAAI,CAAC,KAAM;AACX,OAAK,YAAY,EAAE,MAAM,cAAc,OAAO,CAAC;AACjD;AAQA,eAAsB,gCAAgC,MAKpC;AAChB,MAAI,OAAO,cAAc,eAAe,EAAE,mBAAmB,YAAY;AACvE;AAAA,EACF;AACA,QAAM,OAAO,UAAU,cAAc;AACrC,MAAI,CAAC,KAAM;AACX,OAAK,YAAY;AAAA,IACf,MAAM;AAAA,IACN,KAAK,KAAK;AAAA,IACV,QAAQ,KAAK;AAAA,IACb,SAAS,KAAK;AAAA,IACd,UAAU,KAAK;AAAA,EACjB,CAAC;AACH;","names":[]}