@treeviz/gedcom-parser 2.1.9 → 2.1.11

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.
@@ -93,11 +93,8 @@ var storeCache = {
93
93
  getCacheDbs().relativesOnDegreeCache.setItem(value);
94
94
  }
95
95
  }, 50),
96
- // profilePictureCache IS persisted to IndexedDB
96
+ // Image bytes are stored as one IndexedDB record per photo.
97
97
  profilePictureCache: debounce((value) => {
98
- if (value) {
99
- getCacheDbs().profilePictureCache.setItem(value);
100
- }
101
98
  }, 100)
102
99
  };
103
100
  var cacheInitialized = false;
@@ -106,13 +103,6 @@ var initializeCache = async () => {
106
103
  return;
107
104
  }
108
105
  cacheInitialized = true;
109
- try {
110
- const profilePictureData = await getCacheDbs().profilePictureCache.getItem();
111
- if (profilePictureData) {
112
- caches.profilePictureCache = profilePictureData;
113
- }
114
- } catch (_error) {
115
- }
116
106
  };
117
107
  var resetRelativesCache = () => {
118
108
  caches.relativesOnDegreeCache = {};
@@ -318,6 +308,82 @@ var appendGedcomTrailer = (serialized) => {
318
308
  }
319
309
  return `${trimmed}${newline}0 TRLR`;
320
310
  };
311
+
312
+ // src/utils/media-utils.ts
313
+ var getFileExtension = (filename) => {
314
+ if (!filename) {
315
+ return "";
316
+ }
317
+ if (filename.startsWith("data:")) {
318
+ const mime = filename.slice(5).split(";")[0] || "";
319
+ const subtype = (mime.split("/")[1] || "").toLowerCase();
320
+ if (subtype === "jpeg") {
321
+ return "jpg";
322
+ }
323
+ return subtype.split("+")[0] || "";
324
+ }
325
+ const withoutQuery = filename.split(/[?#]/)[0] || filename;
326
+ const match = withoutQuery.match(/\.([^.]+)$/);
327
+ return match ? match[1].toLowerCase() : "";
328
+ };
329
+ var isImageFormat = (format2) => {
330
+ if (!format2) {
331
+ return false;
332
+ }
333
+ let normalized = format2.toLowerCase().trim();
334
+ if (normalized.startsWith("data:")) {
335
+ normalized = getFileExtension(normalized);
336
+ } else if (normalized.includes("/")) {
337
+ normalized = normalized.split("/")[1]?.split("+")[0] || "";
338
+ if (normalized === "jpeg") {
339
+ normalized = "jpg";
340
+ }
341
+ }
342
+ const imageFormats = [
343
+ "jpg",
344
+ "jpeg",
345
+ "png",
346
+ "gif",
347
+ "bmp",
348
+ "webp",
349
+ "svg",
350
+ "tiff",
351
+ "tif"
352
+ ];
353
+ return imageFormats.includes(normalized);
354
+ };
355
+ var resolveObjeForm = (obje) => {
356
+ const value = obje?.get?.("FILE.FORM")?.toValue?.() ?? obje?.get?.("FORM")?.toValue?.();
357
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
358
+ };
359
+ var mediaIdValue = (obje, path) => {
360
+ const value = obje?.get?.(path)?.toValue?.();
361
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
362
+ };
363
+ var resolveObjeMediaId = (obje) => mediaIdValue(obje, "RIN") || mediaIdValue(obje, "_CLON._OID") || mediaIdValue(obje, "_MSER._LKID") || mediaIdValue(obje, "_OID") || mediaIdValue(obje, "_LKID");
364
+ var ANCESTRY_MEDIA_RETRIEVAL_PREFIX = "https://www.ancestry.com/api/media/retrieval/v2/image";
365
+ var ANCESTRY_MEDIA_QUERY = "client=trees-mediaservice&imageQuality=hq";
366
+ var ancestryMediaPath = (namespace, imgId) => `/namespaces/${namespace}/media/${imgId}?${ANCESTRY_MEDIA_QUERY}`;
367
+ var ancestryMediaFileUrl = (namespace, imgId) => {
368
+ if (!namespace || !imgId) {
369
+ return void 0;
370
+ }
371
+ return `${ANCESTRY_MEDIA_RETRIEVAL_PREFIX}${ancestryMediaPath(namespace, imgId)}`;
372
+ };
373
+ var objeXrefKey = (obje, fallback = 0) => {
374
+ if (typeof obje?.id === "string" && obje.id) {
375
+ return obje.id;
376
+ }
377
+ const value = obje?.toValue?.();
378
+ if (typeof value === "string" && value.trim()) {
379
+ return value.trim();
380
+ }
381
+ if (typeof fallback === "string" && fallback.trim()) {
382
+ return fallback.trim();
383
+ }
384
+ return `@O${fallback}@`;
385
+ };
386
+ var objeNoteValue = (obje) => mediaIdValue(obje, "FILE.NOTE") || mediaIdValue(obje, "NOTE") || "";
321
387
  var List = class _List {
322
388
  // length = 0;
323
389
  constructor(items) {
@@ -967,7 +1033,7 @@ var Common = class _Common {
967
1033
  this,
968
1034
  options.obje.namespace,
969
1035
  options.obje.override,
970
- void 0,
1036
+ this.isAncestry() ? ancestryMediaFileUrl : void 0,
971
1037
  options.gedcomVersion
972
1038
  );
973
1039
  }
@@ -2709,15 +2775,21 @@ var isRemoteOrEmbeddedMediaUrl = (path) => {
2709
2775
  }
2710
2776
  return path.startsWith("data:") || path.startsWith("blob:") || /^https?:\/\//i.test(path);
2711
2777
  };
2712
- var resolveLocalMediaUrl = async (path) => {
2778
+ var resolveLocalMediaUrl = async (path, context) => {
2713
2779
  if (!path) {
2714
2780
  return void 0;
2715
2781
  }
2716
- if (isRemoteOrEmbeddedMediaUrl(path)) {
2782
+ if (path.startsWith("data:") || path.startsWith("blob:")) {
2783
+ return path;
2784
+ }
2785
+ const resolved = await localMediaResolver?.(path, context);
2786
+ if (resolved) {
2787
+ return resolved;
2788
+ }
2789
+ if (/^https?:\/\//i.test(path)) {
2717
2790
  return path;
2718
2791
  }
2719
- const resolved = await localMediaResolver?.(path);
2720
- return resolved;
2792
+ return void 0;
2721
2793
  };
2722
2794
  var blobToDataUrl = async (blob) => {
2723
2795
  const buffer = await blob.arrayBuffer();
@@ -2773,54 +2845,6 @@ var implemented = (type, ...args) => {
2773
2845
  var notImplemented = (type, ...args) => {
2774
2846
  console.error(`[Not Implemented] ${type}`, ...args);
2775
2847
  };
2776
-
2777
- // src/utils/media-utils.ts
2778
- var getFileExtension = (filename) => {
2779
- if (!filename) {
2780
- return "";
2781
- }
2782
- if (filename.startsWith("data:")) {
2783
- const mime = filename.slice(5).split(";")[0] || "";
2784
- const subtype = (mime.split("/")[1] || "").toLowerCase();
2785
- if (subtype === "jpeg") {
2786
- return "jpg";
2787
- }
2788
- return subtype.split("+")[0] || "";
2789
- }
2790
- const withoutQuery = filename.split(/[?#]/)[0] || filename;
2791
- const match = withoutQuery.match(/\.([^.]+)$/);
2792
- return match ? match[1].toLowerCase() : "";
2793
- };
2794
- var isImageFormat = (format2) => {
2795
- if (!format2) {
2796
- return false;
2797
- }
2798
- let normalized = format2.toLowerCase().trim();
2799
- if (normalized.startsWith("data:")) {
2800
- normalized = getFileExtension(normalized);
2801
- } else if (normalized.includes("/")) {
2802
- normalized = normalized.split("/")[1]?.split("+")[0] || "";
2803
- if (normalized === "jpeg") {
2804
- normalized = "jpg";
2805
- }
2806
- }
2807
- const imageFormats = [
2808
- "jpg",
2809
- "jpeg",
2810
- "png",
2811
- "gif",
2812
- "bmp",
2813
- "webp",
2814
- "svg",
2815
- "tiff",
2816
- "tif"
2817
- ];
2818
- return imageFormats.includes(normalized);
2819
- };
2820
- var resolveObjeForm = (obje) => {
2821
- const value = obje?.get?.("FILE.FORM")?.toValue?.() ?? obje?.get?.("FORM")?.toValue?.();
2822
- return typeof value === "string" && value.trim() ? value.trim() : void 0;
2823
- };
2824
2848
  var uniqueItemsCache = /* @__PURE__ */ new WeakMap();
2825
2849
  var setNestedGroup = (obj, key, value, uniqueCounting = true) => {
2826
2850
  const parts = Array.isArray(key) ? key : key.split(/,\s*/);
@@ -4102,22 +4126,19 @@ var Indi = class extends Common {
4102
4126
  if (objeList) {
4103
4127
  await Promise.all(
4104
4128
  objeList.map(async (objeRef) => {
4105
- const key = objeRef?.id;
4129
+ const key = objeXrefKey(objeRef, 0);
4106
4130
  const obje = objeRef?.standardizeMedia(
4107
4131
  namespace,
4108
4132
  true,
4109
- (ns, iId) => {
4110
- return ns && iId ? `https://mediasvc.ancestry.com/v2/image/namespaces/${ns}/media/${iId}?client=trees-mediaservice&imageQuality=hq` : void 0;
4111
- }
4133
+ ancestryMediaFileUrl
4112
4134
  );
4113
4135
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
4114
- const media = obje?.RIN?.toValue() || obje?.get("_OID")?.toValue();
4115
- const clone = obje?.get("_CLON._OID")?.toValue();
4116
- const mser = obje?.get("_MSER._LKID")?.toValue();
4136
+ const media = resolveObjeMediaId(obje);
4117
4137
  let url = obje?.get("FILE")?.toValue();
4118
4138
  const title = obje?.get("FILE.TITL")?.toValue() ?? obje?.get("TITL")?.toValue() ?? "";
4139
+ const note = objeNoteValue(obje);
4119
4140
  const type = resolveObjeForm(obje) ?? (url ? getFileExtension(url) : void 0) ?? "raw";
4120
- let imgId = clone || mser;
4141
+ let imgId = media;
4121
4142
  const hasEmbeddedOrLocalFile = !!url && (url.startsWith("data:") || url.startsWith("blob:") || !/^https?:\/\//i.test(url));
4122
4143
  if (!hasEmbeddedOrLocalFile && (!www || !tree || !this.id)) {
4123
4144
  return;
@@ -4153,6 +4174,7 @@ var Indi = class extends Common {
4153
4174
  imgId,
4154
4175
  person: this.id,
4155
4176
  title,
4177
+ note,
4156
4178
  url,
4157
4179
  contentType: type,
4158
4180
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -4191,7 +4213,7 @@ var Indi = class extends Common {
4191
4213
  return;
4192
4214
  }
4193
4215
  const obje = o;
4194
- const key = `@O${index}@`;
4216
+ const key = objeXrefKey(obje, index);
4195
4217
  obje.standardizeMedia();
4196
4218
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
4197
4219
  const url = obje?.get("FILE")?.toValue();
@@ -4210,6 +4232,7 @@ var Indi = class extends Common {
4210
4232
  imgId,
4211
4233
  person: this.id,
4212
4234
  title,
4235
+ note: objeNoteValue(obje),
4213
4236
  url,
4214
4237
  contentType: type,
4215
4238
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -4318,7 +4341,7 @@ var Indi = class extends Common {
4318
4341
  if (!obje) {
4319
4342
  return;
4320
4343
  }
4321
- const key = `@O${index}@`;
4344
+ const key = objeXrefKey(obje, index);
4322
4345
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
4323
4346
  const url = obje?.get("FILE")?.toValue();
4324
4347
  const title = obje?.get("TITL")?.toValue() ?? "";
@@ -4335,6 +4358,7 @@ var Indi = class extends Common {
4335
4358
  imgId,
4336
4359
  person: this.id,
4337
4360
  title,
4361
+ note: objeNoteValue(obje),
4338
4362
  url,
4339
4363
  contentType: type,
4340
4364
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -4358,7 +4382,7 @@ var Indi = class extends Common {
4358
4382
  if (!obje) {
4359
4383
  return;
4360
4384
  }
4361
- const key = `@O${index}@`;
4385
+ const key = objeXrefKey(obje, index);
4362
4386
  obje.standardizeMedia();
4363
4387
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
4364
4388
  const url = obje?.get("FILE")?.toValue();
@@ -4375,6 +4399,7 @@ var Indi = class extends Common {
4375
4399
  imgId,
4376
4400
  person: this.id,
4377
4401
  title,
4402
+ note: objeNoteValue(obje),
4378
4403
  url,
4379
4404
  contentType: type,
4380
4405
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -4406,7 +4431,12 @@ var Indi = class extends Common {
4406
4431
  );
4407
4432
  if (cached !== void 0) {
4408
4433
  if (cached?.file && !isRemoteOrEmbeddedMediaUrl(cached.file)) {
4409
- const resolvedCached = await resolveLocalMediaUrl(cached.file);
4434
+ const resolvedCached = await resolveLocalMediaUrl(cached.file, {
4435
+ url: cached.file,
4436
+ person: this.id,
4437
+ tree: this.getTreeId?.(),
4438
+ treeName: this.getTreeName?.()
4439
+ });
4410
4440
  if (resolvedCached && isRemoteOrEmbeddedMediaUrl(resolvedCached)) {
4411
4441
  const refreshed = { ...cached, file: resolvedCached };
4412
4442
  profilePictureCache(
@@ -4431,7 +4461,16 @@ var Indi = class extends Common {
4431
4461
  }
4432
4462
  const mediaArray = Object.values(mediaList);
4433
4463
  const toDisplayableProfile = async (media, isPrimary) => {
4434
- const resolvedFile = await resolveLocalMediaUrl(media.url);
4464
+ const resolvedFile = await resolveLocalMediaUrl(media.url, {
4465
+ url: media.url,
4466
+ id: media.id,
4467
+ imgId: media.imgId,
4468
+ key: media.key,
4469
+ contentType: media.contentType,
4470
+ person: media.person || this.id,
4471
+ tree: media.tree || this.getTreeId?.(),
4472
+ treeName: this.getTreeName?.()
4473
+ });
4435
4474
  if (!resolvedFile || !isRemoteOrEmbeddedMediaUrl(resolvedFile)) {
4436
4475
  return void 0;
4437
4476
  }
@@ -8840,7 +8879,9 @@ var downloadGedzipMedia = async (media, onProgress) => {
8840
8879
  id: item.id,
8841
8880
  imgId: item.imgId,
8842
8881
  key: "key" in item ? item.key : void 0,
8843
- contentType: item.contentType
8882
+ contentType: item.contentType,
8883
+ person: "person" in item ? item.person : void 0,
8884
+ tree: "tree" in item ? item.tree : void 0
8844
8885
  });
8845
8886
  if (!resolved?.content) {
8846
8887
  return;
@@ -9365,7 +9406,7 @@ var collectExtensionTagsFrom = (node, into = /* @__PURE__ */ new Set()) => {
9365
9406
  // package.json
9366
9407
  var package_default = {
9367
9408
  name: "@treeviz/gedcom-parser",
9368
- version: "2.1.9"};
9409
+ version: "2.1.11"};
9369
9410
 
9370
9411
  // src/utils/get-product-details.ts
9371
9412
  var isDevelopment = () => {
@@ -9450,16 +9491,26 @@ var Obje = class extends Common {
9450
9491
  if (!this._gedcom) {
9451
9492
  return this;
9452
9493
  }
9494
+ if (typeof this.value === "string" && isId(this.value) && this.refType === "OBJE") {
9495
+ const resolved = this.ref;
9496
+ if (resolved && resolved !== this && typeof resolved.standardizeMedia === "function") {
9497
+ resolved.standardizeMedia(
9498
+ namespace,
9499
+ override,
9500
+ urlGetter,
9501
+ gedcomVersion
9502
+ );
9503
+ return this;
9504
+ }
9505
+ }
9453
9506
  const rin = this?.get("RIN")?.toValue();
9454
- const clone = this?.get("_CLON._OID")?.toValue();
9455
- const mser = this?.get("_MSER._LKID")?.toValue();
9456
9507
  const title = this?.get("FILE.TITL")?.toValue() ?? this?.get("TITL")?.toValue() ?? "";
9457
9508
  const note = this?.get("FILE.NOTE")?.toValue() ?? this?.get("NOTE")?.toValue() ?? "";
9458
9509
  const formRaw = this?.get("FILE.FORM")?.toValue() ?? this?.get("FORM")?.toValue();
9459
9510
  const mediType = this?.get("FILE.FORM.TYPE")?.toValue() ?? this?.get("FORM.TYPE")?.toValue() ?? this?.get("MEDI")?.toValue();
9460
9511
  const file = this?.get("FILE")?.toValue();
9461
- const imgId = rin || clone || mser;
9462
- const url = file || namespace && urlGetter?.(namespace, imgId);
9512
+ const imgId = resolveObjeMediaId(this);
9513
+ const url = file || this.isAncestry() && namespace && urlGetter?.(namespace, imgId);
9463
9514
  if (!url) {
9464
9515
  return this;
9465
9516
  }
@@ -9972,6 +10023,22 @@ var GedCom = class extends Common {
9972
10023
  obje(index) {
9973
10024
  return this.getMain(this.objes(), index);
9974
10025
  }
10026
+ /**
10027
+ * People who link a shared multimedia record (`1 OBJE @On@`), i.e. Ancestry
10028
+ * face tags / everyone the photo is attached to.
10029
+ */
10030
+ indisLinkingObje(objeKey) {
10031
+ const people = [];
10032
+ this.indis()?.forEach((indi) => {
10033
+ const linked = indi?.get("OBJE")?.toList()?.values()?.some(
10034
+ (item) => item?.toValue?.() === objeKey || item?.id === objeKey
10035
+ );
10036
+ if (linked && indi) {
10037
+ people.push(indi);
10038
+ }
10039
+ });
10040
+ return people;
10041
+ }
9975
10042
  sour(index) {
9976
10043
  return this.getMain(this.sours(), index);
9977
10044
  }
@@ -11017,4 +11084,4 @@ var hydrateFromContentAsync = async (content, options) => {
11017
11084
  return hydrateFromContent(content, options);
11018
11085
  };
11019
11086
 
11020
- export { ACCEPTED_DATE_FORMATS, ACCEPTED_DATE_FORMATS_REGEX, DEFAULT_GEDCOM_EXPORT_VERSION, GEDCOM7_CALENDARS, GEDCOM7_PEDI_VALUES, GEDCOM7_RESN_VALUES, GEDCOM7_ROLE_VALUES, GEDCOM7_SEX_VALUES, GEDCOM_EXPORT_VERSIONS, GEDCOM_TRAILER_TAG, GEDZIP_EXTENSION, GEDZIP_GEDCOM_ENTRY, GEDZIP_MIME, parser_default as GedcomTree, PEDIGREE_VALUES, PlaceType, STRUCTURAL_FORMAT, STRUCTURAL_VERSION, TREEVIZ_EXTENSION_BASE_URI, TREEVIZ_EXTENSION_URIS, addFamilyFact, addIndividualFact, addNonEvent, appendGedcomTrailer, applyGedcom7DatePhrases, applyGedcom7Enumerations, applyGedcom7RecordMetadata, attachChildToFamily, attachSpouseToFamily, buildGedzip, buildGedzipBlob, bytesToDataUrl, cacheDiscoveredPath, canAttachAsSpouse, collectExtensionTagsFrom, commonDateFormatter, consolidateChildIntoFamily, coupleKeyForFam, create, createEmptyGedcom, createGedcomUid, dateFormatter, deleteIndividual, downloadGedzipMedia, ensureExtensionSchema, extractGedzip, extractGedzipGedcom, extractSeparationYears, extractSplitPoints, familyHasChild, familyHasParent, findDegenerateFamiliesForIndi, findDuplicateCoupleFamiliesForIndi, findMatchingRangeForSplitRange, findReusableParentChildFamily, firstPointerId, formatGedcom7Timestamp, fromObject, fromObjectAsync, fromTuple, generateSplitRanges, getAllProp, getExtensionSchema, getFamilyWith, getFileExtension, getName, getPlaceParts, getPlaces, getRawSize, getVersion, hungarianOrdinalize, hydrateFromContent, hydrateFromContentAsync, implemented, inRange, inferMediaForm, initializeCache, isDegenerateFamily, isDevelopment, isGedcom7, isGedcomTrailerLine, isGedcomTrailerTag, isGedzipContainer, isImageFormat, isIntersectedRange, isObjePointer, isRangeContained, isRemoteOrEmbeddedMediaUrl, isStructuralEnvelope, makePointer, marriageDateFormatter, mergeDuplicateCoupleFamilies, mergeMediaLists, nameFormatter, nextRecordId, normalizeGedcomVersion, notImplemented, noteDateFormatter, ordinalize, parseGedcom7CalendarPrefix, parseRangeBounds, parseStructuralEnvelope, pathCache, placeTranslator, pointerIds, profilePictureCache, pruneEmptyFamilies, pruneFamiliesByIds, registerExtensionTag, relativesCache, remountGedzipMediaAsDataUrls, removePointerByValue, resetRelativesCache, resolveLocalMediaUrl, resolveMediaContent, resolveObjeForm, rewriteGedcomFilePaths, serializeStructural, setCauseOfDeath, setChildPedigree, setDeceased, setFamilyMarriage, setLocalMediaResolver, setMediaContentResolver, setNestedGroup, splitOverlappingRanges, splitRange, spouseTagFor, toGedcomPedigree, unlinkRelative, updateFactRecord, withGedcom7Calendar };
11087
+ export { ACCEPTED_DATE_FORMATS, ACCEPTED_DATE_FORMATS_REGEX, ANCESTRY_MEDIA_RETRIEVAL_PREFIX, DEFAULT_GEDCOM_EXPORT_VERSION, GEDCOM7_CALENDARS, GEDCOM7_PEDI_VALUES, GEDCOM7_RESN_VALUES, GEDCOM7_ROLE_VALUES, GEDCOM7_SEX_VALUES, GEDCOM_EXPORT_VERSIONS, GEDCOM_TRAILER_TAG, GEDZIP_EXTENSION, GEDZIP_GEDCOM_ENTRY, GEDZIP_MIME, parser_default as GedcomTree, PEDIGREE_VALUES, PlaceType, STRUCTURAL_FORMAT, STRUCTURAL_VERSION, TREEVIZ_EXTENSION_BASE_URI, TREEVIZ_EXTENSION_URIS, addFamilyFact, addIndividualFact, addNonEvent, ancestryMediaFileUrl, appendGedcomTrailer, applyGedcom7DatePhrases, applyGedcom7Enumerations, applyGedcom7RecordMetadata, attachChildToFamily, attachSpouseToFamily, buildGedzip, buildGedzipBlob, bytesToDataUrl, cacheDiscoveredPath, canAttachAsSpouse, collectExtensionTagsFrom, commonDateFormatter, consolidateChildIntoFamily, coupleKeyForFam, create, createEmptyGedcom, createGedcomUid, dateFormatter, deleteIndividual, downloadGedzipMedia, ensureExtensionSchema, extractGedzip, extractGedzipGedcom, extractSeparationYears, extractSplitPoints, familyHasChild, familyHasParent, findDegenerateFamiliesForIndi, findDuplicateCoupleFamiliesForIndi, findMatchingRangeForSplitRange, findReusableParentChildFamily, firstPointerId, formatGedcom7Timestamp, fromObject, fromObjectAsync, fromTuple, generateSplitRanges, getAllProp, getExtensionSchema, getFamilyWith, getFileExtension, getName, getPlaceParts, getPlaces, getRawSize, getVersion, hungarianOrdinalize, hydrateFromContent, hydrateFromContentAsync, implemented, inRange, inferMediaForm, initializeCache, isDegenerateFamily, isDevelopment, isGedcom7, isGedcomTrailerLine, isGedcomTrailerTag, isGedzipContainer, isImageFormat, isIntersectedRange, isObjePointer, isRangeContained, isRemoteOrEmbeddedMediaUrl, isStructuralEnvelope, makePointer, marriageDateFormatter, mergeDuplicateCoupleFamilies, mergeMediaLists, nameFormatter, nextRecordId, normalizeGedcomVersion, notImplemented, noteDateFormatter, objeNoteValue, objeXrefKey, ordinalize, parseGedcom7CalendarPrefix, parseRangeBounds, parseStructuralEnvelope, pathCache, placeTranslator, pointerIds, profilePictureCache, pruneEmptyFamilies, pruneFamiliesByIds, registerExtensionTag, relativesCache, remountGedzipMediaAsDataUrls, removePointerByValue, resetRelativesCache, resolveLocalMediaUrl, resolveMediaContent, resolveObjeForm, resolveObjeMediaId, rewriteGedcomFilePaths, serializeStructural, setCauseOfDeath, setChildPedigree, setDeceased, setFamilyMarriage, setLocalMediaResolver, setMediaContentResolver, setNestedGroup, splitOverlappingRanges, splitRange, spouseTagFor, toGedcomPedigree, unlinkRelative, updateFactRecord, withGedcom7Calendar };
@@ -2,13 +2,16 @@
2
2
  * Optional resolvers for local / cached media (GEDZIP paths, IndexedDB, etc.).
3
3
  * The visualiser injects storage lookups; the parser stays host-agnostic.
4
4
  */
5
- export type LocalMediaResolver = (path: string) => Promise<string | undefined> | string | undefined;
5
+ export type LocalMediaResolver = (path: string, context?: MediaContentLookup) => Promise<string | undefined> | string | undefined;
6
6
  export type MediaContentLookup = {
7
7
  url?: string;
8
8
  id?: string;
9
9
  imgId?: string;
10
10
  key?: string;
11
11
  contentType?: string;
12
+ person?: string;
13
+ tree?: string;
14
+ treeName?: string;
12
15
  };
13
16
  export type MediaContentResult = {
14
17
  content: string;
@@ -20,9 +23,10 @@ export declare const setMediaContentResolver: (resolver?: MediaContentResolver)
20
23
  export declare const isRemoteOrEmbeddedMediaUrl: (path?: string) => boolean;
21
24
  /**
22
25
  * Resolve a FILE payload to a browser-displayable URL when possible.
23
- * Leaves http(s)/data/blob URLs unchanged; asks the injected resolver for local paths.
26
+ * Remote http(s) URLs go through the host resolver so they can be cached.
27
+ * Local GEDZIP paths are resolved via the injected lookup.
24
28
  */
25
- export declare const resolveLocalMediaUrl: (path?: string) => Promise<string | undefined>;
29
+ export declare const resolveLocalMediaUrl: (path?: string, context?: MediaContentLookup) => Promise<string | undefined>;
26
30
  /**
27
31
  * Resolve media bytes for GEDZIP export: host cache → local path → data URL → fetch.
28
32
  */
@@ -1 +1 @@
1
- {"version":3,"file":"local-media.d.ts","sourceRoot":"","sources":["../../src/utils/local-media.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAChC,IAAI,EAAE,MAAM,KACR,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;AAEtD,MAAM,MAAM,kBAAkB,GAAG;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,CAClC,KAAK,EAAE,kBAAkB,KAEvB,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,GACvC,kBAAkB,GAClB,SAAS,CAAC;AAKb,eAAO,MAAM,qBAAqB,GAAI,WAAW,kBAAkB,SAElE,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,WAAW,oBAAoB,SAEtE,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAI,OAAO,MAAM,YASvD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAU,OAAO,MAAM,gCAUvD,CAAC;AAiBF;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAC/B,OAAO,kBAAkB,KACvB,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAwCxC,CAAC"}
1
+ {"version":3,"file":"local-media.d.ts","sourceRoot":"","sources":["../../src/utils/local-media.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,kBAAkB,KACxB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;AAEtD,MAAM,MAAM,kBAAkB,GAAG;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,CAClC,KAAK,EAAE,kBAAkB,KAEvB,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,GACvC,kBAAkB,GAClB,SAAS,CAAC;AAKb,eAAO,MAAM,qBAAqB,GAAI,WAAW,kBAAkB,SAElE,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,WAAW,oBAAoB,SAEtE,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAI,OAAO,MAAM,YASvD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAChC,OAAO,MAAM,EACb,UAAU,kBAAkB,gCAgB5B,CAAC;AAiBF;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAC/B,OAAO,kBAAkB,KACvB,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAwCxC,CAAC"}
@@ -14,4 +14,24 @@ export declare const resolveObjeForm: (obje?: {
14
14
  toValue?: () => unknown;
15
15
  } | undefined;
16
16
  }) => string | undefined;
17
+ type ObjeGetter = {
18
+ get?: (path: MultiTag) => {
19
+ toValue?: () => unknown;
20
+ } | undefined;
21
+ };
22
+ /**
23
+ * Ancestry (and similar) media identity. Shared `0 @On@ OBJE` records often
24
+ * have `_OID` without `_MSER._LKID`; both are the UUID used in media URLs.
25
+ */
26
+ export declare const resolveObjeMediaId: (obje?: ObjeGetter) => string | undefined;
27
+ /** Ancestry tree media host used by their viewer. */
28
+ export declare const ANCESTRY_MEDIA_RETRIEVAL_PREFIX = "https://www.ancestry.com/api/media/retrieval/v2/image";
29
+ export declare const ancestryMediaFileUrl: (namespace?: string | number, imgId?: string) => string | undefined;
30
+ /** Xref on a shared `0 @On@ OBJE` record, or the pointer payload, or a list key/index. */
31
+ export declare const objeXrefKey: (obje?: {
32
+ id?: string;
33
+ toValue?: () => unknown;
34
+ }, fallback?: string | number) => string;
35
+ export declare const objeNoteValue: (obje?: ObjeGetter) => string;
36
+ export {};
17
37
  //# sourceMappingURL=media-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"media-utils.d.ts","sourceRoot":"","sources":["../../src/utils/media-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,eAAO,MAAM,gBAAgB,GAAI,UAAU,MAAM,KAAG,MAenD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ,MAAM,KAAG,OAyB9C,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,eAAe,GAAI,OAAO;IACtC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK;QAAE,OAAO,CAAC,EAAE,MAAM,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC;CAClE,KAAG,MAAM,GAAG,SAKZ,CAAC"}
1
+ {"version":3,"file":"media-utils.d.ts","sourceRoot":"","sources":["../../src/utils/media-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,eAAO,MAAM,gBAAgB,GAAI,UAAU,MAAM,KAAG,MAenD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ,MAAM,KAAG,OAyB9C,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,eAAe,GAAI,OAAO;IACtC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK;QAAE,OAAO,CAAC,EAAE,MAAM,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC;CAClE,KAAG,MAAM,GAAG,SAKZ,CAAC;AAEF,KAAK,UAAU,GAAG;IACjB,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK;QAAE,OAAO,CAAC,EAAE,MAAM,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC;CAClE,CAAC;AAOF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,UAAU,KAAG,MAAM,GAAG,SAKpC,CAAC;AAE7B,qDAAqD;AACrD,eAAO,MAAM,+BAA+B,0DACY,CAAC;AAMzD,eAAO,MAAM,oBAAoB,GAChC,YAAY,MAAM,GAAG,MAAM,EAC3B,QAAQ,MAAM,KACZ,MAAM,GAAG,SAKX,CAAC;AAEF,0FAA0F;AAC1F,eAAO,MAAM,WAAW,GACvB,OAAO;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,OAAO,CAAA;CAAE,EAC/C,WAAU,MAAM,GAAG,MAAU,KAC3B,MAYF,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,OAAO,UAAU,KAAG,MACkB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeviz/gedcom-parser",
3
- "version": "2.1.9",
3
+ "version": "2.1.11",
4
4
  "description": "Lightweight, pluggable GEDCOM parser for JavaScript/TypeScript with optional caching and place matching. Zero browser dependencies.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",