@tinytars/frame 0.1.23 → 0.1.25

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.
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Attachment } from "./attachment-types";
3
3
  import AttachmentViewer from "./AttachmentViewer.svelte";
4
+ import { uniqueByKey } from "./attachments";
4
5
 
5
6
  // The one shared display for a leaf's attachments[]: a row of small thumbnail chips (image
6
7
  // preview, or a document glyph for anything else), each opening the in-app viewer
@@ -16,7 +17,9 @@
16
17
  productName: string;
17
18
  onRemove?: (a: Attachment) => void;
18
19
  }
19
- let { attachments, clientId = null, attachmentUrl, productName, onRemove }: Props = $props();
20
+ let { attachments: given, clientId = null, attachmentUrl, productName, onRemove }: Props = $props();
21
+ // Items saved before appendAttachments deduped can already hold the same key twice.
22
+ const attachments = $derived(uniqueByKey(given));
20
23
 
21
24
  let openIndex = $state<number | null>(null);
22
25
 
package/attachments.ts ADDED
@@ -0,0 +1,9 @@
1
+ import type { Attachment } from "./attachment-types";
2
+
3
+ // Keys are content-addressed (sha8-filename), so the same file attached twice yields the same key —
4
+ // and a keyed {#each} over a list holding it twice throws each_key_duplicate. First occurrence wins.
5
+ export function uniqueByKey<T extends Pick<Attachment, "key">>(attachments: readonly T[]): T[] {
6
+ const byKey = new Map<string, T>();
7
+ for (const a of attachments) if (!byKey.has(a.key)) byKey.set(a.key, a);
8
+ return [...byKey.values()];
9
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinytars/frame",
3
- "version": "0.1.23",
3
+ "version": "0.1.25",
4
4
  "description": "Domain-neutral Svelte app-shell: session/auth controllers, account chrome, and menu/card/modal primitives built on @tinytars/vault.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -31,6 +31,7 @@
31
31
  "./AccountMenu.svelte": "./AccountMenu.svelte",
32
32
  "./anchored-menu.svelte": "./anchored-menu.svelte.ts",
33
33
  "./attach-controller": "./attach-controller.ts",
34
+ "./attachments": "./attachments.ts",
34
35
  "./AttachmentStrip.svelte": "./AttachmentStrip.svelte",
35
36
  "./AttachmentViewer.svelte": "./AttachmentViewer.svelte",
36
37
  "./AttachPicker.svelte": "./AttachPicker.svelte",