@ai-matrx/media 0.1.0 → 0.2.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,72 @@
1
1
  # @ai-matrx/media
2
2
 
3
+ ## 0.2.0 — 2026-08-29
4
+
5
+ **THE SHARE MANDATE row is satisfied (wave M-SHARE, ruling C19).** The
6
+ share-popover BODIES land, additively, through the exact `MediaActionsPort` /
7
+ `SharePopover` contract 0.1.0 reserved for them — no breaking change, no
8
+ change to any existing entry's surface.
9
+
10
+ - **New entry `@ai-matrx/media/share`** (`"use client"` group):
11
+ - `MediaSharePopover` — the complete share body, ported from the canonical
12
+ matrx-frontend share flows (`ImageSharePopover` / `VideoSharePopover` —
13
+ ONE share mechanism) with the seams inverted:
14
+ - the public-link path (permanent CDN URL for public files, else
15
+ reuse-or-mint a no-expiry read-only share link) rides the ONE
16
+ `MediaClient.shareableUrl` door, asked on click; `null` **fails
17
+ closed** (law 4) and renders as inline error state;
18
+ - external refs get the simplified copy-external-link surface
19
+ (`shareableUrl` prefetched — pure classification there);
20
+ - "Manage all links" → the `manageLinks` host callback and the access
21
+ summary → the `AccessSummary` host slot (both iam surfaces are app
22
+ content per C8; rows/sections hide when unbound);
23
+ - toasts → the optional `notify` adapter; every failure ALSO renders
24
+ inline so no outcome is silent without one;
25
+ - **association affordances** ("Linked to" rows with live titles +
26
+ detach, "Attach to…" universal search + attach) consume
27
+ `@ai-matrx/associations` strictly through its public
28
+ provider/hooks surface, and degrade to ABSENT when no
29
+ `AssociationsProvider` is mounted.
30
+ - `createMediaSharePopover(options)` — binds the host-shaped options once
31
+ and returns a component matching the `SharePopover` slot exactly; the
32
+ tarball canary compiles that assignment with no cast.
33
+ - **Dependency direction:** `@ai-matrx/associations` is an **OPTIONAL peer**
34
+ (`>=0.4.0`) carried ONLY by `/share` — a media consumer of `.`, `/core`,
35
+ or `/react` never installs it (C8). Upgrading associations requires no
36
+ media release: the popover reaches it through the host-mounted provider.
37
+ - Six new inlined SVG glyphs (lucide v1.22.0: globe, link-2, settings-2,
38
+ loader-circle, plus, search) per C19 — still no icon library.
39
+ - Gates extended: the five-laws source scan covers the new files
40
+ automatically; `verify:tarball` now installs the PUBLISHED associations +
41
+ design-system packages and imports/requires `/share` from the packed
42
+ artifact, renders it without a provider (degradation proof), and
43
+ type-checks the no-cast `SharePopover` slot assignment.
44
+
45
+ **Deliberate divergences from the origin popovers** (seam-forced, not
46
+ defects): the three public-link label states ("Copy" vs "Create + copy",
47
+ CDN-vs-link sublabels) collapse to one label — link inventory lives behind
48
+ the host's `shareableUrl`; the mobile Drawer/desktop Popover split stays with
49
+ the shells/hosts (this is the BODY, positioned by its opener); the
50
+ `ShareLinkDialog` itself remains host content (C8) behind `manageLinks`.
51
+
52
+ ## 0.1.1 — 2026-08-29
53
+
54
+ Types-only fix; runtime behavior unchanged.
55
+
56
+ - **Fixed: the `DurableSrc` unique-symbol brand was duplicated in the built
57
+ declarations.** The dts was built in two passes (mirroring the two-config
58
+ "use client" banner split), so the root `index.d.ts` declared its own copy
59
+ of the brand while `/core` and `/react` used a shared-chunk copy — two
60
+ distinct `unique symbol`s. Result: a `MediaClient` typed via the root entry
61
+ was nominally incompatible with `/core`'s `MediaProvider`, forcing a
62
+ documented cast in the host. The dts now builds in ONE pass over all three
63
+ entries (the JS banner split is unchanged), so the brand is declared once
64
+ in `index.d.ts` and the other entries' declarations import it.
65
+ - **Canary added:** `verify:tarball` now compiles a consumer against the
66
+ packed tarball that assigns a root-typed `MediaClient` into
67
+ `/core`'s `MediaProvider` props with **no cast** — the brand-duplication
68
+ regression class fails `check:package` from now on.
69
+
3
70
  ## 0.1.0 — 2026-08-29
4
71
 
5
72
  Initial release (campaign ruling C19). Root types + `/core` headless hooks +
package/README.md CHANGED
@@ -15,6 +15,7 @@ correct path is the only path the types allow.
15
15
  @ai-matrx/media types only — MediaRef, DurableSrc, MediaClient, host ports
16
16
  @ai-matrx/media/core headless React hooks (platform-free state machines)
17
17
  @ai-matrx/media/react DOM components (Tailwind classes, inlined SVG icons)
18
+ @ai-matrx/media/share the complete share popover body (optional peer: @ai-matrx/associations)
18
19
  ```
19
20
 
20
21
  ## The rules the types enforce
@@ -86,6 +87,42 @@ without touching this package.
86
87
  </MediaProvider>
87
88
  ```
88
89
 
90
+ ### The complete share body (`/share`)
91
+
92
+ `/share` ships the popover BODY the slot was reserved for — the canonical
93
+ Matrx share experience:
94
+
95
+ - **Copy public link** — one click asks `MediaClient.shareableUrl(ref)` for
96
+ the truly-permanent URL (the host's implementation reuses or mints a
97
+ no-expiry share link, or returns the permanent CDN URL for public files)
98
+ and copies it. `null` fails closed — never a signed URL.
99
+ - **External refs** get the simplified surface: the safe external URL or a
100
+ disabled row.
101
+ - **Manage all links** / **who-can-see-this** are host slots
102
+ (`manageLinks` callback, `AccessSummary` component) — link inventory and
103
+ reachability live with the host's iam surfaces.
104
+ - **Linked to / Attach to…** — the association affordances, riding
105
+ `@ai-matrx/associations` through its public hooks. They light up when an
106
+ `AssociationsProvider` is mounted above and degrade to absent when not.
107
+
108
+ ```tsx
109
+ import { createMediaSharePopover } from "@ai-matrx/media/share";
110
+
111
+ const SharePopover = createMediaSharePopover({
112
+ manageLinks: (ctx) => openShareLinkDialog(ctx), // optional
113
+ AccessSummary, // optional host panel
114
+ notify: { success: toast.success, error: toast.error }, // optional
115
+ });
116
+
117
+ <MediaProvider client={client} ports={{ actions: { SharePopover, download, copy } }}>
118
+ {/* every toolbar/lightbox now opens the full share experience */}
119
+ </MediaProvider>
120
+ ```
121
+
122
+ Only `/share` carries the `@ai-matrx/associations` peer (optional — install
123
+ it, plus `@ai-matrx/design-system` which its `/react` entry loads, to use
124
+ this entry). The other entries never do.
125
+
89
126
  ## Styling
90
127
 
91
128
  `/react` uses Tailwind utility classes with semantic tokens (`bg-muted`,
@@ -97,9 +134,9 @@ without touching this package.
97
134
 
98
135
  ## SSR / RSC
99
136
 
100
- The root entry is server-safe (types + one pure function). `/core` and
101
- `/react` are client modules (`"use client"` is stamped per entry). Nothing
102
- touches `window` at import time.
137
+ The root entry is server-safe (types + one pure function). `/core`, `/react`
138
+ and `/share` are client modules (`"use client"` is stamped per entry).
139
+ Nothing touches `window` at import time.
103
140
 
104
141
  ## License
105
142
 
package/dist/core.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { M as MediaClient, a as MediaHostPorts, b as MediaRefLike, c as MediaResolution, d as MediaUnavailableReason, D as DurableSrc, e as MediaActionContext, f as MediaActionKind, g as MediaSlotComponent, h as MediaSharePopoverProps } from './use-media-upload-VjUhqbyY.cjs';
4
- export { i as MediaUploadEntry, j as MediaUploadEntryStatus, k as MediaUploadProgress, U as UseMediaUploadResult, u as useMediaUpload } from './use-media-upload-VjUhqbyY.cjs';
3
+ import { MediaClient, MediaHostPorts, MediaRefLike, MediaResolution, MediaUnavailableReason, DurableSrc, MediaActionContext, MediaActionKind, MediaSlotComponent, MediaSharePopoverProps } from './index.cjs';
4
+ export { M as MediaUploadEntry, a as MediaUploadEntryStatus, b as MediaUploadProgress, U as UseMediaUploadResult, u as useMediaUpload } from './use-media-upload-v5Uq9Ruq.cjs';
5
5
 
6
6
  interface MediaProviderProps {
7
7
  client: MediaClient;
package/dist/core.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { M as MediaClient, a as MediaHostPorts, b as MediaRefLike, c as MediaResolution, d as MediaUnavailableReason, D as DurableSrc, e as MediaActionContext, f as MediaActionKind, g as MediaSlotComponent, h as MediaSharePopoverProps } from './use-media-upload-VjUhqbyY.js';
4
- export { i as MediaUploadEntry, j as MediaUploadEntryStatus, k as MediaUploadProgress, U as UseMediaUploadResult, u as useMediaUpload } from './use-media-upload-VjUhqbyY.js';
3
+ import { MediaClient, MediaHostPorts, MediaRefLike, MediaResolution, MediaUnavailableReason, DurableSrc, MediaActionContext, MediaActionKind, MediaSlotComponent, MediaSharePopoverProps } from './index.js';
4
+ export { M as MediaUploadEntry, a as MediaUploadEntryStatus, b as MediaUploadProgress, U as UseMediaUploadResult, u as useMediaUpload } from './use-media-upload-Dg2HSvTq.js';
5
5
 
6
6
  interface MediaProviderProps {
7
7
  client: MediaClient;
package/dist/react.cjs CHANGED
@@ -42,16 +42,22 @@ __export(react_exports, {
42
42
  FileVideoIcon: () => FileVideoIcon,
43
43
  FolderIcon: () => FolderIcon,
44
44
  FolderOpenIcon: () => FolderOpenIcon,
45
+ GlobeIcon: () => GlobeIcon,
45
46
  ImageIcon: () => ImageIcon,
46
47
  ImageOffIcon: () => ImageOffIcon,
47
48
  InlineMediaRef: () => InlineMediaRef,
49
+ Link2Icon: () => Link2Icon,
48
50
  MediaActionToolbar: () => MediaActionToolbar,
49
51
  MediaLightbox: () => MediaLightbox,
50
52
  MediaThumbnail: () => MediaThumbnail,
51
53
  MusicIcon: () => MusicIcon,
52
54
  PackageBoxIcon: () => PackageBoxIcon,
53
55
  PenToolIcon: () => PenToolIcon,
56
+ PlusIcon: () => PlusIcon,
57
+ SearchIcon: () => SearchIcon,
58
+ Settings2Icon: () => Settings2Icon,
54
59
  Share2Icon: () => Share2Icon,
60
+ SpinnerIcon: () => SpinnerIcon,
55
61
  SubtitlesIcon: () => SubtitlesIcon,
56
62
  UploadIcon: () => UploadIcon,
57
63
  UploadProgressList: () => UploadProgressList,
@@ -308,6 +314,43 @@ function CheckCircle2Icon(props) {
308
314
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m9 11 3 3L22 4" })
309
315
  ] });
310
316
  }
317
+ function GlobeIcon(props) {
318
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
319
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
320
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" }),
321
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M2 12h20" })
322
+ ] });
323
+ }
324
+ function Link2Icon(props) {
325
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
326
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9 17H7A5 5 0 0 1 7 7h2" }),
327
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M15 7h2a5 5 0 1 1 0 10h-2" }),
328
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "8", x2: "16", y1: "12", y2: "12" })
329
+ ] });
330
+ }
331
+ function Settings2Icon(props) {
332
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
333
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M20 7h-9" }),
334
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 17H5" }),
335
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "17", cy: "17", r: "3" }),
336
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "7", cy: "7", r: "3" })
337
+ ] });
338
+ }
339
+ function SpinnerIcon(props) {
340
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { ...svgProps(props), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) });
341
+ }
342
+ function PlusIcon(props) {
343
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
344
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M5 12h14" }),
345
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 5v14" })
346
+ ] });
347
+ }
348
+ function SearchIcon(props) {
349
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgProps(props), children: [
350
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "11", cy: "11", r: "8" }),
351
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m21 21-4.3-4.3" })
352
+ ] });
353
+ }
311
354
 
312
355
  // src/core/file-kind.ts
313
356
  var ROWS = [