taglib-wasm 1.2.2 → 1.3.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 (32) hide show
  1. package/dist/index.browser.js +212 -89
  2. package/dist/simple.browser.js +212 -89
  3. package/dist/src/constants/complex-properties.d.ts +0 -14
  4. package/dist/src/constants/complex-properties.d.ts.map +1 -1
  5. package/dist/src/msgpack/encoder.d.ts +6 -0
  6. package/dist/src/msgpack/encoder.d.ts.map +1 -1
  7. package/dist/src/msgpack/encoder.js +12 -0
  8. package/dist/src/runtime/wasi-adapter/file-handle.d.ts +3 -1
  9. package/dist/src/runtime/wasi-adapter/file-handle.d.ts.map +1 -1
  10. package/dist/src/runtime/wasi-adapter/file-handle.js +17 -0
  11. package/dist/src/runtime/wasi-memory.d.ts +0 -5
  12. package/dist/src/runtime/wasi-memory.d.ts.map +1 -1
  13. package/dist/src/runtime/wasi-memory.js +1 -8
  14. package/dist/src/taglib/audio-file-base.d.ts.map +1 -1
  15. package/dist/src/taglib/audio-file-base.js +12 -0
  16. package/dist/src/taglib/audio-file-impl.d.ts.map +1 -1
  17. package/dist/src/taglib/audio-file-impl.js +22 -39
  18. package/dist/src/taglib/embind-adapter.d.ts.map +1 -1
  19. package/dist/src/taglib/embind-adapter.js +18 -0
  20. package/dist/src/taglib/extra-state-registry.d.ts +26 -0
  21. package/dist/src/taglib/extra-state-registry.d.ts.map +1 -0
  22. package/dist/src/taglib/extra-state-registry.js +59 -0
  23. package/dist/src/taglib/mutable-tag.d.ts +7 -0
  24. package/dist/src/taglib/mutable-tag.d.ts.map +1 -1
  25. package/dist/src/taglib/save-reconstruct.d.ts +13 -0
  26. package/dist/src/taglib/save-reconstruct.d.ts.map +1 -0
  27. package/dist/src/taglib/save-reconstruct.js +39 -0
  28. package/dist/src/version.d.ts +1 -1
  29. package/dist/src/version.js +1 -1
  30. package/dist/src/wasm.d.ts +14 -0
  31. package/dist/src/wasm.d.ts.map +1 -1
  32. package/package.json +1 -1
@@ -3,15 +3,10 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  import { PICTURE_TYPE_NAMES, PICTURE_TYPE_VALUES } from "../types.js";
5
5
  import * as bwf from "./audio-file-bwf.js";
6
- import {
7
- FileOperationError,
8
- InvalidFormatError,
9
- UnsupportedFormatError
10
- } from "../errors.js";
11
- import { readFileData } from "../utils/file.js";
6
+ import { FileOperationError, UnsupportedFormatError } from "../errors.js";
12
7
  import { writeFileData } from "../utils/write.js";
13
8
  import { BaseAudioFileImpl } from "./audio-file-base.js";
14
- import { wrapEmbindHandle } from "./embind-adapter.js";
9
+ import { saveViaFreshHandle } from "./save-reconstruct.js";
15
10
  let _nodeFs;
16
11
  function sortChapters(list) {
17
12
  return [...list].sort((a, b) => a.startTimeMs - b.startTimeMs);
@@ -79,38 +74,23 @@ class AudioFileImpl extends BaseAudioFileImpl {
79
74
  );
80
75
  }
81
76
  if (this.isPartiallyLoaded && this.originalSource) {
82
- const rawFullHandle = this.module.createFileHandle();
83
- const fullFileHandle = this.module.isWasi ? rawFullHandle : wrapEmbindHandle(rawFullHandle);
84
- try {
85
- const success = await (async () => {
86
- const data = await readFileData(this.originalSource);
87
- return fullFileHandle.loadFromBuffer(data);
88
- })();
89
- if (!success) {
90
- throw new InvalidFormatError(
91
- "Failed to load full audio file for saving"
92
- );
93
- }
94
- fullFileHandle.setTagData(this.handle.getTagData());
95
- fullFileHandle.setProperties(this.handle.getProperties());
96
- fullFileHandle.setPictures(this.handle.getPictures());
97
- const bextBytes = this.handle.getBextData();
98
- if (bextBytes !== void 0) fullFileHandle.setBextData(bextBytes);
99
- const ixmlStr = this.handle.getIxml();
100
- if (ixmlStr !== void 0) fullFileHandle.setIxml(ixmlStr);
101
- if (!fullFileHandle.save()) {
102
- throw new FileOperationError(
103
- "save",
104
- "Failed to save changes to full file"
105
- );
106
- }
107
- const buffer = fullFileHandle.getBuffer();
108
- await writeFileData(targetPath, buffer);
109
- } finally {
110
- fullFileHandle.destroy();
111
- }
77
+ await saveViaFreshHandle(
78
+ this.module,
79
+ this.handle,
80
+ this.originalSource,
81
+ targetPath,
82
+ false
83
+ );
112
84
  this.isPartiallyLoaded = false;
113
85
  this.originalSource = void 0;
86
+ } else if (this.module.isWasi && this.sourcePath && targetPath !== this.sourcePath) {
87
+ await saveViaFreshHandle(
88
+ this.module,
89
+ this.handle,
90
+ this.sourcePath,
91
+ targetPath,
92
+ true
93
+ );
114
94
  } else {
115
95
  if (!this.save()) {
116
96
  throw new FileOperationError(
@@ -172,13 +152,16 @@ class AudioFileImpl extends BaseAudioFileImpl {
172
152
  }
173
153
  const sorted = sortChapters(chapters);
174
154
  const trackEndMs = this.audioProperties()?.durationMs;
155
+ const style = options?.mp4ChapterStyle ?? "quicktime";
156
+ const source = fmt === "MP4" ? style : "id3";
175
157
  const raw = sorted.map((c, i) => ({
176
158
  id: c.id,
177
159
  startTimeMs: c.startTimeMs,
178
160
  endTimeMs: inferEndTimeMs(sorted, i, trackEndMs) ?? c.startTimeMs,
179
- title: c.title
161
+ title: c.title,
162
+ source
180
163
  }));
181
- this.handle.setChapters(raw, options?.mp4ChapterStyle ?? "quicktime");
164
+ this.handle.setChapters(raw, style);
182
165
  }
183
166
  getBext() {
184
167
  return bwf.getBext(this.handle);
@@ -1 +1 @@
1
- {"version":3,"file":"embind-adapter.d.ts","sourceRoot":"","sources":["../../../src/taglib/embind-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAc7C,wEAAwE;AACxE,UAAU,gBAAgB;IACxB,KAAK,IAAI,MAAM,CAAC;IAChB,MAAM,IAAI,MAAM,CAAC;IACjB,KAAK,IAAI,MAAM,CAAC;IAChB,OAAO,IAAI,MAAM,CAAC;IAClB,KAAK,IAAI,MAAM,CAAC;IAChB,IAAI,IAAI,MAAM,CAAC;IACf,KAAK,IAAI,MAAM,CAAC;IAChB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,oFAAoF;AACpF,UAAU,4BAA4B;IACpC,eAAe,IAAI,MAAM,CAAC;IAC1B,oBAAoB,IAAI,MAAM,CAAC;IAC/B,OAAO,IAAI,MAAM,CAAC;IAClB,UAAU,IAAI,MAAM,CAAC;IACrB,QAAQ,IAAI,MAAM,CAAC;IACnB,aAAa,IAAI,MAAM,CAAC;IACxB,KAAK,IAAI,MAAM,CAAC;IAChB,eAAe,IAAI,MAAM,CAAC;IAC1B,UAAU,IAAI,OAAO,CAAC;IACtB,WAAW,IAAI,MAAM,CAAC;IACtB,SAAS,IAAI,MAAM,CAAC;IACpB,WAAW,IAAI,OAAO,CAAC;IACvB,aAAa,IAAI,MAAM,CAAC;IACxB,WAAW,IAAI,MAAM,CAAC;IACtB,YAAY,IAAI,MAAM,CAAC;CACxB;AAED,6DAA6D;AAC7D,MAAM,WAAW,gBAAgB;IAC/B,MAAM,IAAI,gBAAgB,CAAC;IAC3B,kBAAkB,IAAI,4BAA4B,GAAG,IAAI,CAAC;IAC1D,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,wFAAwF;AACxF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,GAAG,UAAU,CA6FlE"}
1
+ {"version":3,"file":"embind-adapter.d.ts","sourceRoot":"","sources":["../../../src/taglib/embind-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,YAAY,CAAC;AAcxD,wEAAwE;AACxE,UAAU,gBAAgB;IACxB,KAAK,IAAI,MAAM,CAAC;IAChB,MAAM,IAAI,MAAM,CAAC;IACjB,KAAK,IAAI,MAAM,CAAC;IAChB,OAAO,IAAI,MAAM,CAAC;IAClB,KAAK,IAAI,MAAM,CAAC;IAChB,IAAI,IAAI,MAAM,CAAC;IACf,KAAK,IAAI,MAAM,CAAC;IAChB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,oFAAoF;AACpF,UAAU,4BAA4B;IACpC,eAAe,IAAI,MAAM,CAAC;IAC1B,oBAAoB,IAAI,MAAM,CAAC;IAC/B,OAAO,IAAI,MAAM,CAAC;IAClB,UAAU,IAAI,MAAM,CAAC;IACrB,QAAQ,IAAI,MAAM,CAAC;IACnB,aAAa,IAAI,MAAM,CAAC;IACxB,KAAK,IAAI,MAAM,CAAC;IAChB,eAAe,IAAI,MAAM,CAAC;IAC1B,UAAU,IAAI,OAAO,CAAC;IACtB,WAAW,IAAI,MAAM,CAAC;IACtB,SAAS,IAAI,MAAM,CAAC;IACpB,WAAW,IAAI,OAAO,CAAC;IACvB,aAAa,IAAI,MAAM,CAAC;IACxB,WAAW,IAAI,MAAM,CAAC;IACtB,YAAY,IAAI,MAAM,CAAC;CACxB;AAED,6DAA6D;AAC7D,MAAM,WAAW,gBAAgB;IAC/B,MAAM,IAAI,gBAAgB,CAAC;IAC3B,kBAAkB,IAAI,4BAA4B,GAAG,IAAI,CAAC;IAC1D,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,wFAAwF;AACxF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,GAAG,UAAU,CAoHlE"}
@@ -43,6 +43,24 @@ function wrapEmbindHandle(raw) {
43
43
  data ?? null
44
44
  );
45
45
  },
46
+ // Emscripten exposes USLT only through the PropertyMap "LYRICS" key (no
47
+ // dedicated Embind binding), so bridge get/setLyrics to get/setProperties.
48
+ // Text only — language/description are not surfaced by the PropertyMap.
49
+ getLyrics() {
50
+ const props = raw.getProperties();
51
+ return (props["LYRICS"] ?? []).map((text) => ({
52
+ text,
53
+ description: "",
54
+ language: ""
55
+ }));
56
+ },
57
+ setLyrics(lyrics) {
58
+ const handle = raw;
59
+ const props = handle.getProperties();
60
+ if (lyrics.length > 0) props["LYRICS"] = lyrics.map((l) => l.text);
61
+ else delete props["LYRICS"];
62
+ handle.setProperties(props);
63
+ },
46
64
  hasId3Tags() {
47
65
  const v = raw.hasId3Tags();
48
66
  if (!v || typeof v !== "object") return { v1: false, v2: false };
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Single registry of "extra" editable state (everything beyond basic tags and
3
+ * the text PropertyMap) that must survive a file reconstruct in
4
+ * {@link saveViaFreshHandle}. Adding a new metadata kind is ONE entry here; the
5
+ * `extra-state-registry.test.ts` coverage check fails CI if a passthrough field
6
+ * is added without a registry entry, so a field can no longer be silently
7
+ * dropped on save (the taglib-upg class of bug).
8
+ */
9
+ import type { FileHandle } from "../wasm.js";
10
+ type ExtraField = {
11
+ /** Stable name, used by the test-net coverage check. */
12
+ readonly name: string;
13
+ /**
14
+ * Copy this field from `source` onto `target`. `sourceComplete` is true when
15
+ * `source` holds the file's full state (WASI save-as): empty/absent means
16
+ * "explicitly cleared" and is propagated. It is false for partial loads,
17
+ * where empty may just mean "not read from the truncated middle" — those are
18
+ * skipped so the freshly-reloaded full handle keeps its originals.
19
+ */
20
+ copy(target: FileHandle, source: FileHandle, sourceComplete: boolean): void;
21
+ };
22
+ export declare const EXTRA_FIELDS: readonly ExtraField[];
23
+ /** Copy every registered extra-state field from `source` onto `target`. */
24
+ export declare function copyExtraState(target: FileHandle, source: FileHandle, sourceComplete: boolean): void;
25
+ export {};
26
+ //# sourceMappingURL=extra-state-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extra-state-registry.d.ts","sourceRoot":"","sources":["../../../src/taglib/extra-state-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,YAAY,CAAC;AAEzD,KAAK,UAAU,GAAG;IAChB,wDAAwD;IACxD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;;OAMG;IACH,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,OAAO,GAAG,IAAI,CAAC;CAC7E,CAAC;AAWF,eAAO,MAAM,YAAY,EAAE,SAAS,UAAU,EA6C7C,CAAC;AAEF,2EAA2E;AAC3E,wBAAgB,cAAc,CAC5B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,UAAU,EAClB,cAAc,EAAE,OAAO,GACtB,IAAI,CAIN"}
@@ -0,0 +1,59 @@
1
+ function chapterStyle(chapters) {
2
+ const s = chapters[0]?.source;
3
+ return s === "nero" || s === "both" ? s : "quicktime";
4
+ }
5
+ const EXTRA_FIELDS = [
6
+ {
7
+ name: "pictures",
8
+ copy(target, source, complete) {
9
+ const v = source.getPictures();
10
+ if (complete || v.length > 0) target.setPictures(v);
11
+ }
12
+ },
13
+ {
14
+ name: "ratings",
15
+ copy(target, source, complete) {
16
+ const v = source.getRatings();
17
+ if (complete || v.length > 0) target.setRatings(v);
18
+ }
19
+ },
20
+ {
21
+ name: "lyrics",
22
+ copy(target, source, complete) {
23
+ const v = source.getLyrics();
24
+ if (complete || v.length > 0) target.setLyrics(v);
25
+ }
26
+ },
27
+ {
28
+ name: "chapters",
29
+ copy(target, source, complete) {
30
+ const v = source.getChapters();
31
+ if (complete || v.length > 0) target.setChapters(v, chapterStyle(v));
32
+ }
33
+ },
34
+ {
35
+ name: "bextData",
36
+ copy(target, source, complete) {
37
+ const v = source.getBextData();
38
+ if (v !== void 0) target.setBextData(v);
39
+ else if (complete) target.setBextData(null);
40
+ }
41
+ },
42
+ {
43
+ name: "ixml",
44
+ copy(target, source, complete) {
45
+ const v = source.getIxml();
46
+ if (v !== void 0) target.setIxml(v);
47
+ else if (complete) target.setIxml(null);
48
+ }
49
+ }
50
+ ];
51
+ function copyExtraState(target, source, sourceComplete) {
52
+ for (const field of EXTRA_FIELDS) {
53
+ field.copy(target, source, sourceComplete);
54
+ }
55
+ }
56
+ export {
57
+ EXTRA_FIELDS,
58
+ copyExtraState
59
+ };
@@ -34,6 +34,8 @@ export interface MutableTag {
34
34
  readonly genre?: string;
35
35
  /** Year */
36
36
  readonly year?: number;
37
+ /** Full release date, e.g. "1975-10-31" or "1975". Lossless companion to {@link year}. */
38
+ readonly date?: string;
37
39
  /** Track number */
38
40
  readonly track?: number;
39
41
  /** Set the track title */
@@ -48,6 +50,11 @@ export interface MutableTag {
48
50
  setGenre(value: string): MutableTag;
49
51
  /** Set the release year */
50
52
  setYear(value: number): MutableTag;
53
+ /**
54
+ * Set the full release date at ISO precision (e.g. "1975-10-31"); `year` resyncs to the
55
+ * leading year. `setDate("")` clears the date AND year together.
56
+ */
57
+ setDate(value: string): MutableTag;
51
58
  /** Set the track number */
52
59
  setTrack(value: number): MutableTag;
53
60
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mutable-tag.d.ts","sourceRoot":"","sources":["../../../src/taglib/mutable-tag.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,UAAU;IACzB,kBAAkB;IAClB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB;IAClB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB;IACjB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc;IACd,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY;IACZ,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW;IACX,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB;IACnB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,0BAA0B;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IACpC,0BAA0B;IAC1B,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IACrC,yBAAyB;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IACpC,sBAAsB;IACtB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IACtC,oBAAoB;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IACpC,2BAA2B;IAC3B,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IACnC,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;CACrC"}
1
+ {"version":3,"file":"mutable-tag.d.ts","sourceRoot":"","sources":["../../../src/taglib/mutable-tag.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,UAAU;IACzB,kBAAkB;IAClB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB;IAClB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB;IACjB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc;IACd,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY;IACZ,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW;IACX,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,0FAA0F;IAC1F,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB;IACnB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,0BAA0B;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IACpC,0BAA0B;IAC1B,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IACrC,yBAAyB;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IACpC,sBAAsB;IACtB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IACtC,oBAAoB;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IACpC,2BAA2B;IAC3B,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IACnC;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IACnC,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;CACrC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Full-file reconstruct used by `saveToFile` for the two cases where the
3
+ * editing handle does not itself hold the complete file bytes: an Emscripten
4
+ * partial load, and the WASI path-mode "save as". Both must produce a complete
5
+ * file at the target without mutating the editing handle's source in place.
6
+ */
7
+ import type { FileHandle, TagLibModule } from "../wasm.js";
8
+ /**
9
+ * Reload the full file from `source` into a fresh handle, apply the editing
10
+ * handle's state, save, and write the result to `targetPath`.
11
+ */
12
+ export declare function saveViaFreshHandle(module: TagLibModule, editing: FileHandle, source: string | Uint8Array | ArrayBuffer | File, targetPath: string, sourceComplete: boolean): Promise<void>;
13
+ //# sourceMappingURL=save-reconstruct.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save-reconstruct.d.ts","sourceRoot":"","sources":["../../../src/taglib/save-reconstruct.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAgC3D;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,IAAI,EAChD,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,OAAO,GACtB,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
@@ -0,0 +1,39 @@
1
+ import { FileOperationError, InvalidFormatError } from "../errors.js";
2
+ import { readFileData } from "../utils/file.js";
3
+ import { writeFileData } from "../utils/write.js";
4
+ import { wrapEmbindHandle } from "./embind-adapter.js";
5
+ import { copyExtraState } from "./extra-state-registry.js";
6
+ function copyEditedState(target, source, sourceComplete) {
7
+ target.setTagData(source.getTagData());
8
+ target.setProperties(
9
+ sourceComplete ? source.getProperties() : { ...target.getProperties(), ...source.getProperties() }
10
+ );
11
+ copyExtraState(target, source, sourceComplete);
12
+ }
13
+ async function saveViaFreshHandle(module, editing, source, targetPath, sourceComplete) {
14
+ const rawFullHandle = module.createFileHandle();
15
+ const fullFileHandle = module.isWasi ? rawFullHandle : wrapEmbindHandle(rawFullHandle);
16
+ try {
17
+ {
18
+ const data = await readFileData(source);
19
+ if (!fullFileHandle.loadFromBuffer(data)) {
20
+ throw new InvalidFormatError(
21
+ "Failed to load full audio file for saving"
22
+ );
23
+ }
24
+ }
25
+ copyEditedState(fullFileHandle, editing, sourceComplete);
26
+ if (!fullFileHandle.save()) {
27
+ throw new FileOperationError(
28
+ "save",
29
+ "Failed to save changes to full file"
30
+ );
31
+ }
32
+ await writeFileData(targetPath, fullFileHandle.getBuffer());
33
+ } finally {
34
+ fullFileHandle.destroy();
35
+ }
36
+ }
37
+ export {
38
+ saveViaFreshHandle
39
+ };
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "1.2.2";
1
+ export declare const VERSION = "1.3.0";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1,4 +1,4 @@
1
- const VERSION = "1.2.2";
1
+ const VERSION = "1.3.0";
2
2
  export {
3
3
  VERSION
4
4
  };
@@ -16,6 +16,18 @@ export interface RawChapter {
16
16
  id?: string;
17
17
  source?: string;
18
18
  }
19
+ /**
20
+ * Raw unsynchronized-lyrics entry as carried across the backend boundary.
21
+ * Both backends persist `text` only: lyrics ride the text "LYRICS" PropertyMap
22
+ * key (TagLib has no LYRICS *complex* property), so `description`/`language` are
23
+ * kept in-memory for the current handle but are NOT written to the file and read
24
+ * back as `""` (taglib-gq9). Full structured USLT is a possible future addition.
25
+ */
26
+ export interface RawLyrics {
27
+ text: string;
28
+ description: string;
29
+ language: string;
30
+ }
19
31
  export interface EmscriptenModule {
20
32
  HEAP8: Int8Array;
21
33
  HEAP16: Int16Array;
@@ -79,6 +91,8 @@ export interface FileHandle {
79
91
  email?: string;
80
92
  counter?: number;
81
93
  }[]): void;
94
+ getLyrics(): RawLyrics[];
95
+ setLyrics(lyrics: RawLyrics[]): void;
82
96
  hasId3Tags(): {
83
97
  v1: boolean;
84
98
  v2: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"wasm.d.ts","sourceRoot":"","sources":["../../src/wasm.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wasm.d.ts","sourceRoot":"","sources":["../../src/wasm.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taglib-wasm",
3
- "version": "1.2.2",
3
+ "version": "1.3.0",
4
4
  "description": "TagLib-Wasm is the universal tagging library for TypeScript/JavaScript platforms: Browsers, Node.js, Deno, Bun, Cloudflare Workers, and Electron apps",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",