@singi-labs/sifa-sdk 0.7.7 → 0.7.8

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/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as ProfileSkill, L as LocationValue, a as PdsProviderInfo } from './index-IxlRuFsK.cjs';
2
- export { A as ActiveApp, E as Endorsement, b as EndorsementData, c as ExternalAccount, d as ExternalAccountKeytraceClaim, F as FeedItem, e as LanguageProficiency, f as Profile, g as ProfileCertification, h as ProfileCourse, i as ProfileEducation, j as ProfileHonor, k as ProfileIndustry, l as ProfileLanguage, m as ProfileLocation, n as ProfileOverrideSource, o as ProfilePosition, p as ProfileProject, q as ProfilePublication, r as ProfileVolunteering, s as PublicationContributor, S as SkillRef, t as SkillSuggestion, T as TrustStat, V as VerifiedAccount } from './index-IxlRuFsK.cjs';
1
+ import { P as ProfileSkill, L as LocationValue, a as PdsProviderInfo, b as Profile } from './index-D0a04T88.cjs';
2
+ export { A as ActiveApp, E as Endorsement, c as EndorsementData, d as ExternalAccount, e as ExternalAccountKeytraceClaim, F as FeedItem, f as LanguageProficiency, g as ProfileCertification, h as ProfileCourse, i as ProfileEducation, j as ProfileHonor, k as ProfileIndustry, l as ProfileLanguage, m as ProfileLocation, n as ProfileOverrideSource, o as ProfilePosition, p as ProfileProject, q as ProfilePublication, r as ProfileVolunteering, s as PublicationContributor, S as SkillRef, t as SkillSuggestion, T as TrustStat, V as VerifiedAccount } from './index-D0a04T88.cjs';
3
3
  export { EndorsementConfirmationRecord, EndorsementConfirmationRecordSchema, EndorsementRecord, EndorsementRecordSchema, GraphFollowRecord, GraphFollowRecordSchema, ProfileCertificationRecord, ProfileCertificationRecordSchema, ProfileCourseRecord, ProfileCourseRecordSchema, ProfileEducationRecord, ProfileEducationRecordSchema, ProfileExternalAccountRecord, ProfileExternalAccountRecordSchema, ProfileHonorRecord, ProfileHonorRecordSchema, ProfileLanguageRecord, ProfileLanguageRecordSchema, ProfilePositionRecord, ProfilePositionRecordSchema, ProfileProjectRecord, ProfileProjectRecordSchema, ProfilePublicationRecord, ProfilePublicationRecordSchema, ProfileSelfRecord, ProfileSelfRecordSchema, ProfileSkillRecord, ProfileSkillRecordSchema, ProfileVolunteeringRecord, ProfileVolunteeringRecordSchema, PublicationAuthor, PublicationAuthorSchema, atUriSchema, cidSchema, datetimeSchema, didSchema, languageTagSchema, maxGraphemes, selfLabelsSchema, strongRefSchema, uriSchema } from './schemas/index.cjs';
4
4
  import 'zod';
5
5
 
@@ -281,6 +281,56 @@ declare function completenessScore(c: ProfileCompletion): number;
281
281
  /** Completion as a rounded 0..100 integer percent (matches API serialisation). */
282
282
  declare function completenessPercent(c: ProfileCompletion): number;
283
283
 
284
+ /**
285
+ * Profile dimensions -- the routing signal used by the Sifa homepage to choose
286
+ * between the V3 "still building" and V4 "established" variants.
287
+ *
288
+ * Six binary signals, equal weight: avatar, headline, about, current position,
289
+ * minimum-skill threshold, and at least one education entry. The routing
290
+ * threshold itself (e.g. ">= 4 of 6 -> ESTABLISHED") lives in the consumer
291
+ * because different surfaces may want to cut at different bars over time.
292
+ *
293
+ * Canonical source of truth for dimension scoring across Sifa clients.
294
+ * sifa-api computes the underlying `ProfileDimensionInputs` shape inline
295
+ * (in SQL on the session route) but defers scoring to this module so the
296
+ * frontend and backend cannot drift on what "filled" means.
297
+ *
298
+ * See `docs/plans/2026-04-27-homepage-variants.md` (sifa-web) for the
299
+ * history of why these six were chosen over the original eight.
300
+ */
301
+
302
+ declare const DIMENSIONS_MAX_SCORE = 6;
303
+ declare const MIN_SKILLS = 3;
304
+ type DimensionKey = 'avatar' | 'headline' | 'about' | 'currentPosition' | 'skills' | 'education';
305
+ type DimensionMap = Record<DimensionKey, boolean>;
306
+ /**
307
+ * Minimal raw inputs needed to compute the dimension map. sifa-api can
308
+ * populate this from a single composite SQL query without loading the full
309
+ * Profile shape, which is the whole point of putting this in the SDK.
310
+ */
311
+ interface ProfileDimensionInputs {
312
+ hasAvatar: boolean;
313
+ hasHeadline: boolean;
314
+ hasAbout: boolean;
315
+ currentPositionCount: number;
316
+ skillCount: number;
317
+ educationCount: number;
318
+ }
319
+ /**
320
+ * Pure-TS computation of the 6-key boolean map from minimal inputs.
321
+ * Use this when you already have aggregate counts (e.g. server-side).
322
+ */
323
+ declare function dimensionsFromInputs(inputs: ProfileDimensionInputs): DimensionMap;
324
+ /**
325
+ * Derives `ProfileDimensionInputs` from a full Profile. Use this on the
326
+ * client when you already have the profile loaded.
327
+ */
328
+ declare function profileToDimensionInputs(profile: Profile): ProfileDimensionInputs;
329
+ /** Convenience: full Profile -> dimension boolean map. */
330
+ declare function getFilledDimensionsMap(profile: Profile): DimensionMap;
331
+ /** Count of filled dimensions, 0..6. Accepts either raw inputs or a full Profile. */
332
+ declare function countFilledDimensions(input: ProfileDimensionInputs | Profile): number;
333
+
284
334
  /**
285
335
  * Sifa SDK -- public client library for the Sifa AppView on AT Protocol.
286
336
  *
@@ -290,4 +340,4 @@ declare function completenessPercent(c: ProfileCompletion): number;
290
340
  */
291
341
  declare const SIFA_SDK_VERSION: string;
292
342
 
293
- export { CATEGORY_LABELS, CATEGORY_ORDER, COMPLETENESS_MAX_SCORE, CONTINENTS, COUNTRIES, type ContinentCode, INDUSTRY_OPTIONS, type IndustryOption, LocationValue, type MergedProfileSkill, PLATFORM_LABELS, PLATFORM_OPTIONS, type PdsProvider, PdsProviderInfo, type PlatformId, type ProfileCompletion, ProfileSkill, type RgbColor, SIFA_SDK_VERSION, SKILL_CATEGORIES, type SkillCategory, certDateExtractor, completenessPercent, completenessScore, contrastRatio, countryCodeToFlag, dateRangeExtractor, dedupeSkills, detectPdsProvider, findIndustry, formatDistanceToNow, formatLocation, formatRelativeTime, getContinent, getDisplayLabel, getFaviconUrl, getHandleStem, getIndustryLabelKey, getPdsDisplayName, getPlatformLabel, groupSkillsByCategory, isKnownPlatform, isValidRgbColor, lexiconDateExtractor, meetsContrastAA, parseLocationString, pdsProviderFromApi, relativeLuminance, rgbToString, sanitizeHandleInput, singleDateExtractor, sortByDateDesc, truncateGraphemes };
343
+ export { CATEGORY_LABELS, CATEGORY_ORDER, COMPLETENESS_MAX_SCORE, CONTINENTS, COUNTRIES, type ContinentCode, DIMENSIONS_MAX_SCORE, type DimensionKey, type DimensionMap, INDUSTRY_OPTIONS, type IndustryOption, LocationValue, MIN_SKILLS, type MergedProfileSkill, PLATFORM_LABELS, PLATFORM_OPTIONS, type PdsProvider, PdsProviderInfo, type PlatformId, Profile, type ProfileCompletion, type ProfileDimensionInputs, ProfileSkill, type RgbColor, SIFA_SDK_VERSION, SKILL_CATEGORIES, type SkillCategory, certDateExtractor, completenessPercent, completenessScore, contrastRatio, countFilledDimensions, countryCodeToFlag, dateRangeExtractor, dedupeSkills, detectPdsProvider, dimensionsFromInputs, findIndustry, formatDistanceToNow, formatLocation, formatRelativeTime, getContinent, getDisplayLabel, getFaviconUrl, getFilledDimensionsMap, getHandleStem, getIndustryLabelKey, getPdsDisplayName, getPlatformLabel, groupSkillsByCategory, isKnownPlatform, isValidRgbColor, lexiconDateExtractor, meetsContrastAA, parseLocationString, pdsProviderFromApi, profileToDimensionInputs, relativeLuminance, rgbToString, sanitizeHandleInput, singleDateExtractor, sortByDateDesc, truncateGraphemes };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as ProfileSkill, L as LocationValue, a as PdsProviderInfo } from './index-IxlRuFsK.js';
2
- export { A as ActiveApp, E as Endorsement, b as EndorsementData, c as ExternalAccount, d as ExternalAccountKeytraceClaim, F as FeedItem, e as LanguageProficiency, f as Profile, g as ProfileCertification, h as ProfileCourse, i as ProfileEducation, j as ProfileHonor, k as ProfileIndustry, l as ProfileLanguage, m as ProfileLocation, n as ProfileOverrideSource, o as ProfilePosition, p as ProfileProject, q as ProfilePublication, r as ProfileVolunteering, s as PublicationContributor, S as SkillRef, t as SkillSuggestion, T as TrustStat, V as VerifiedAccount } from './index-IxlRuFsK.js';
1
+ import { P as ProfileSkill, L as LocationValue, a as PdsProviderInfo, b as Profile } from './index-D0a04T88.js';
2
+ export { A as ActiveApp, E as Endorsement, c as EndorsementData, d as ExternalAccount, e as ExternalAccountKeytraceClaim, F as FeedItem, f as LanguageProficiency, g as ProfileCertification, h as ProfileCourse, i as ProfileEducation, j as ProfileHonor, k as ProfileIndustry, l as ProfileLanguage, m as ProfileLocation, n as ProfileOverrideSource, o as ProfilePosition, p as ProfileProject, q as ProfilePublication, r as ProfileVolunteering, s as PublicationContributor, S as SkillRef, t as SkillSuggestion, T as TrustStat, V as VerifiedAccount } from './index-D0a04T88.js';
3
3
  export { EndorsementConfirmationRecord, EndorsementConfirmationRecordSchema, EndorsementRecord, EndorsementRecordSchema, GraphFollowRecord, GraphFollowRecordSchema, ProfileCertificationRecord, ProfileCertificationRecordSchema, ProfileCourseRecord, ProfileCourseRecordSchema, ProfileEducationRecord, ProfileEducationRecordSchema, ProfileExternalAccountRecord, ProfileExternalAccountRecordSchema, ProfileHonorRecord, ProfileHonorRecordSchema, ProfileLanguageRecord, ProfileLanguageRecordSchema, ProfilePositionRecord, ProfilePositionRecordSchema, ProfileProjectRecord, ProfileProjectRecordSchema, ProfilePublicationRecord, ProfilePublicationRecordSchema, ProfileSelfRecord, ProfileSelfRecordSchema, ProfileSkillRecord, ProfileSkillRecordSchema, ProfileVolunteeringRecord, ProfileVolunteeringRecordSchema, PublicationAuthor, PublicationAuthorSchema, atUriSchema, cidSchema, datetimeSchema, didSchema, languageTagSchema, maxGraphemes, selfLabelsSchema, strongRefSchema, uriSchema } from './schemas/index.js';
4
4
  import 'zod';
5
5
 
@@ -281,6 +281,56 @@ declare function completenessScore(c: ProfileCompletion): number;
281
281
  /** Completion as a rounded 0..100 integer percent (matches API serialisation). */
282
282
  declare function completenessPercent(c: ProfileCompletion): number;
283
283
 
284
+ /**
285
+ * Profile dimensions -- the routing signal used by the Sifa homepage to choose
286
+ * between the V3 "still building" and V4 "established" variants.
287
+ *
288
+ * Six binary signals, equal weight: avatar, headline, about, current position,
289
+ * minimum-skill threshold, and at least one education entry. The routing
290
+ * threshold itself (e.g. ">= 4 of 6 -> ESTABLISHED") lives in the consumer
291
+ * because different surfaces may want to cut at different bars over time.
292
+ *
293
+ * Canonical source of truth for dimension scoring across Sifa clients.
294
+ * sifa-api computes the underlying `ProfileDimensionInputs` shape inline
295
+ * (in SQL on the session route) but defers scoring to this module so the
296
+ * frontend and backend cannot drift on what "filled" means.
297
+ *
298
+ * See `docs/plans/2026-04-27-homepage-variants.md` (sifa-web) for the
299
+ * history of why these six were chosen over the original eight.
300
+ */
301
+
302
+ declare const DIMENSIONS_MAX_SCORE = 6;
303
+ declare const MIN_SKILLS = 3;
304
+ type DimensionKey = 'avatar' | 'headline' | 'about' | 'currentPosition' | 'skills' | 'education';
305
+ type DimensionMap = Record<DimensionKey, boolean>;
306
+ /**
307
+ * Minimal raw inputs needed to compute the dimension map. sifa-api can
308
+ * populate this from a single composite SQL query without loading the full
309
+ * Profile shape, which is the whole point of putting this in the SDK.
310
+ */
311
+ interface ProfileDimensionInputs {
312
+ hasAvatar: boolean;
313
+ hasHeadline: boolean;
314
+ hasAbout: boolean;
315
+ currentPositionCount: number;
316
+ skillCount: number;
317
+ educationCount: number;
318
+ }
319
+ /**
320
+ * Pure-TS computation of the 6-key boolean map from minimal inputs.
321
+ * Use this when you already have aggregate counts (e.g. server-side).
322
+ */
323
+ declare function dimensionsFromInputs(inputs: ProfileDimensionInputs): DimensionMap;
324
+ /**
325
+ * Derives `ProfileDimensionInputs` from a full Profile. Use this on the
326
+ * client when you already have the profile loaded.
327
+ */
328
+ declare function profileToDimensionInputs(profile: Profile): ProfileDimensionInputs;
329
+ /** Convenience: full Profile -> dimension boolean map. */
330
+ declare function getFilledDimensionsMap(profile: Profile): DimensionMap;
331
+ /** Count of filled dimensions, 0..6. Accepts either raw inputs or a full Profile. */
332
+ declare function countFilledDimensions(input: ProfileDimensionInputs | Profile): number;
333
+
284
334
  /**
285
335
  * Sifa SDK -- public client library for the Sifa AppView on AT Protocol.
286
336
  *
@@ -290,4 +340,4 @@ declare function completenessPercent(c: ProfileCompletion): number;
290
340
  */
291
341
  declare const SIFA_SDK_VERSION: string;
292
342
 
293
- export { CATEGORY_LABELS, CATEGORY_ORDER, COMPLETENESS_MAX_SCORE, CONTINENTS, COUNTRIES, type ContinentCode, INDUSTRY_OPTIONS, type IndustryOption, LocationValue, type MergedProfileSkill, PLATFORM_LABELS, PLATFORM_OPTIONS, type PdsProvider, PdsProviderInfo, type PlatformId, type ProfileCompletion, ProfileSkill, type RgbColor, SIFA_SDK_VERSION, SKILL_CATEGORIES, type SkillCategory, certDateExtractor, completenessPercent, completenessScore, contrastRatio, countryCodeToFlag, dateRangeExtractor, dedupeSkills, detectPdsProvider, findIndustry, formatDistanceToNow, formatLocation, formatRelativeTime, getContinent, getDisplayLabel, getFaviconUrl, getHandleStem, getIndustryLabelKey, getPdsDisplayName, getPlatformLabel, groupSkillsByCategory, isKnownPlatform, isValidRgbColor, lexiconDateExtractor, meetsContrastAA, parseLocationString, pdsProviderFromApi, relativeLuminance, rgbToString, sanitizeHandleInput, singleDateExtractor, sortByDateDesc, truncateGraphemes };
343
+ export { CATEGORY_LABELS, CATEGORY_ORDER, COMPLETENESS_MAX_SCORE, CONTINENTS, COUNTRIES, type ContinentCode, DIMENSIONS_MAX_SCORE, type DimensionKey, type DimensionMap, INDUSTRY_OPTIONS, type IndustryOption, LocationValue, MIN_SKILLS, type MergedProfileSkill, PLATFORM_LABELS, PLATFORM_OPTIONS, type PdsProvider, PdsProviderInfo, type PlatformId, Profile, type ProfileCompletion, type ProfileDimensionInputs, ProfileSkill, type RgbColor, SIFA_SDK_VERSION, SKILL_CATEGORIES, type SkillCategory, certDateExtractor, completenessPercent, completenessScore, contrastRatio, countFilledDimensions, countryCodeToFlag, dateRangeExtractor, dedupeSkills, detectPdsProvider, dimensionsFromInputs, findIndustry, formatDistanceToNow, formatLocation, formatRelativeTime, getContinent, getDisplayLabel, getFaviconUrl, getFilledDimensionsMap, getHandleStem, getIndustryLabelKey, getPdsDisplayName, getPlatformLabel, groupSkillsByCategory, isKnownPlatform, isValidRgbColor, lexiconDateExtractor, meetsContrastAA, parseLocationString, pdsProviderFromApi, profileToDimensionInputs, relativeLuminance, rgbToString, sanitizeHandleInput, singleDateExtractor, sortByDateDesc, truncateGraphemes };
package/dist/index.js CHANGED
@@ -942,6 +942,48 @@ function completenessScore(c) {
942
942
  function completenessPercent(c) {
943
943
  return Math.round(completenessScore(c) / COMPLETENESS_MAX_SCORE * 100);
944
944
  }
945
+
946
+ // src/logic/profile-dimensions.ts
947
+ var DIMENSIONS_MAX_SCORE = 6;
948
+ var MIN_SKILLS = 3;
949
+ function nonEmptyString(value) {
950
+ return typeof value === "string" && value.trim().length > 0;
951
+ }
952
+ function dimensionsFromInputs(inputs) {
953
+ return {
954
+ avatar: inputs.hasAvatar,
955
+ headline: inputs.hasHeadline,
956
+ about: inputs.hasAbout,
957
+ currentPosition: inputs.currentPositionCount > 0,
958
+ skills: inputs.skillCount >= MIN_SKILLS,
959
+ education: inputs.educationCount > 0
960
+ };
961
+ }
962
+ function profileToDimensionInputs(profile) {
963
+ const positions = profile.positions ?? [];
964
+ const skills = profile.skills ?? [];
965
+ const education = profile.education ?? [];
966
+ const currentPositionCount = positions.filter((p) => !p.endedAt).length;
967
+ return {
968
+ hasAvatar: nonEmptyString(profile.avatar),
969
+ hasHeadline: nonEmptyString(profile.headline),
970
+ hasAbout: nonEmptyString(profile.about),
971
+ currentPositionCount,
972
+ skillCount: skills.length,
973
+ educationCount: education.length
974
+ };
975
+ }
976
+ function getFilledDimensionsMap(profile) {
977
+ return dimensionsFromInputs(profileToDimensionInputs(profile));
978
+ }
979
+ function countFilledDimensions(input) {
980
+ const map = "hasAvatar" in input ? dimensionsFromInputs(input) : getFilledDimensionsMap(input);
981
+ let n = 0;
982
+ for (const v of Object.values(map)) {
983
+ if (v) n++;
984
+ }
985
+ return n;
986
+ }
945
987
  function maxGraphemes(max) {
946
988
  return (value) => {
947
989
  const segmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
@@ -1102,8 +1144,8 @@ var ProfileVolunteeringRecordSchema = z.object({
1102
1144
  });
1103
1145
 
1104
1146
  // src/index.ts
1105
- var SIFA_SDK_VERSION = "0.7.7";
1147
+ var SIFA_SDK_VERSION = "0.7.8";
1106
1148
 
1107
- export { CATEGORY_LABELS, CATEGORY_ORDER, COMPLETENESS_MAX_SCORE, CONTINENTS, COUNTRIES, EndorsementConfirmationRecordSchema, EndorsementRecordSchema, GraphFollowRecordSchema, INDUSTRY_OPTIONS, PLATFORM_LABELS, PLATFORM_OPTIONS, ProfileCertificationRecordSchema, ProfileCourseRecordSchema, ProfileEducationRecordSchema, ProfileExternalAccountRecordSchema, ProfileHonorRecordSchema, ProfileLanguageRecordSchema, ProfilePositionRecordSchema, ProfileProjectRecordSchema, ProfilePublicationRecordSchema, ProfileSelfRecordSchema, ProfileSkillRecordSchema, ProfileVolunteeringRecordSchema, PublicationAuthorSchema, SIFA_SDK_VERSION, SKILL_CATEGORIES, atUriSchema, certDateExtractor, cidSchema, completenessPercent, completenessScore, contrastRatio, countryCodeToFlag, dateRangeExtractor, datetimeSchema, dedupeSkills, detectPdsProvider, didSchema, findIndustry, formatDistanceToNow, formatLocation, formatRelativeTime, getContinent, getDisplayLabel, getFaviconUrl, getHandleStem, getIndustryLabelKey, getPdsDisplayName, getPlatformLabel, groupSkillsByCategory, isKnownPlatform, isValidRgbColor, languageTagSchema, lexiconDateExtractor, maxGraphemes, meetsContrastAA, parseLocationString, pdsProviderFromApi, relativeLuminance, rgbToString, sanitizeHandleInput, selfLabelsSchema, singleDateExtractor, sortByDateDesc, strongRefSchema, truncateGraphemes, uriSchema };
1149
+ export { CATEGORY_LABELS, CATEGORY_ORDER, COMPLETENESS_MAX_SCORE, CONTINENTS, COUNTRIES, DIMENSIONS_MAX_SCORE, EndorsementConfirmationRecordSchema, EndorsementRecordSchema, GraphFollowRecordSchema, INDUSTRY_OPTIONS, MIN_SKILLS, PLATFORM_LABELS, PLATFORM_OPTIONS, ProfileCertificationRecordSchema, ProfileCourseRecordSchema, ProfileEducationRecordSchema, ProfileExternalAccountRecordSchema, ProfileHonorRecordSchema, ProfileLanguageRecordSchema, ProfilePositionRecordSchema, ProfileProjectRecordSchema, ProfilePublicationRecordSchema, ProfileSelfRecordSchema, ProfileSkillRecordSchema, ProfileVolunteeringRecordSchema, PublicationAuthorSchema, SIFA_SDK_VERSION, SKILL_CATEGORIES, atUriSchema, certDateExtractor, cidSchema, completenessPercent, completenessScore, contrastRatio, countFilledDimensions, countryCodeToFlag, dateRangeExtractor, datetimeSchema, dedupeSkills, detectPdsProvider, didSchema, dimensionsFromInputs, findIndustry, formatDistanceToNow, formatLocation, formatRelativeTime, getContinent, getDisplayLabel, getFaviconUrl, getFilledDimensionsMap, getHandleStem, getIndustryLabelKey, getPdsDisplayName, getPlatformLabel, groupSkillsByCategory, isKnownPlatform, isValidRgbColor, languageTagSchema, lexiconDateExtractor, maxGraphemes, meetsContrastAA, parseLocationString, pdsProviderFromApi, profileToDimensionInputs, relativeLuminance, rgbToString, sanitizeHandleInput, selfLabelsSchema, singleDateExtractor, sortByDateDesc, strongRefSchema, truncateGraphemes, uriSchema };
1108
1150
  //# sourceMappingURL=index.js.map
1109
1151
  //# sourceMappingURL=index.js.map