@milaboratories/pl-model-common 1.31.2 → 1.32.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 (42) hide show
  1. package/dist/drivers/index.d.ts +4 -4
  2. package/dist/drivers/pframe/index.d.ts +4 -4
  3. package/dist/drivers/pframe/query/index.d.ts +2 -2
  4. package/dist/drivers/pframe/query/query_common.d.ts +39 -1
  5. package/dist/drivers/pframe/query/query_common.d.ts.map +1 -1
  6. package/dist/drivers/pframe/query/query_data.d.ts +18 -3
  7. package/dist/drivers/pframe/query/query_data.d.ts.map +1 -1
  8. package/dist/drivers/pframe/query/query_spec.d.ts +14 -3
  9. package/dist/drivers/pframe/query/query_spec.d.ts.map +1 -1
  10. package/dist/drivers/pframe/query/utils.cjs +27 -0
  11. package/dist/drivers/pframe/query/utils.cjs.map +1 -1
  12. package/dist/drivers/pframe/query/utils.d.ts.map +1 -1
  13. package/dist/drivers/pframe/query/utils.js +27 -0
  14. package/dist/drivers/pframe/query/utils.js.map +1 -1
  15. package/dist/drivers/pframe/spec/anchored.cjs.map +1 -1
  16. package/dist/drivers/pframe/spec/anchored.d.ts +3 -3
  17. package/dist/drivers/pframe/spec/anchored.d.ts.map +1 -1
  18. package/dist/drivers/pframe/spec/anchored.js.map +1 -1
  19. package/dist/drivers/pframe/spec/index.d.ts +1 -1
  20. package/dist/drivers/pframe/spec/spec.cjs +8 -3
  21. package/dist/drivers/pframe/spec/spec.cjs.map +1 -1
  22. package/dist/drivers/pframe/spec/spec.d.ts +15 -2
  23. package/dist/drivers/pframe/spec/spec.d.ts.map +1 -1
  24. package/dist/drivers/pframe/spec/spec.js +8 -3
  25. package/dist/drivers/pframe/spec/spec.js.map +1 -1
  26. package/dist/drivers/pframe/spec_driver.d.ts +37 -2
  27. package/dist/drivers/pframe/spec_driver.d.ts.map +1 -1
  28. package/dist/index.d.ts +5 -5
  29. package/dist/services/service_types.cjs.map +1 -1
  30. package/dist/services/service_types.d.ts +7 -7
  31. package/dist/services/service_types.d.ts.map +1 -1
  32. package/dist/services/service_types.js.map +1 -1
  33. package/package.json +6 -6
  34. package/src/drivers/pframe/query/query_common.ts +39 -0
  35. package/src/drivers/pframe/query/query_data.ts +20 -0
  36. package/src/drivers/pframe/query/query_spec.ts +17 -0
  37. package/src/drivers/pframe/query/utils.test.ts +37 -0
  38. package/src/drivers/pframe/query/utils.ts +25 -0
  39. package/src/drivers/pframe/spec/anchored.ts +8 -3
  40. package/src/drivers/pframe/spec/spec.ts +19 -6
  41. package/src/drivers/pframe/spec_driver.ts +42 -1
  42. package/src/services/service_types.ts +1 -6
@@ -9,7 +9,7 @@ import { SUniversalPColumnId, UniversalPColumnId } from "./ids.js";
9
9
  * Maintains maps of known domain values and axes that can be referenced by anchors
10
10
  */
11
11
  declare class AnchoredIdDeriver {
12
- readonly anchors: Record<string, PColumnSpec>;
12
+ readonly anchors: Record<string, Pick<PColumnSpec, "axesSpec" | "domain" | "contextDomain">>;
13
13
  private readonly domains;
14
14
  private readonly contextDomains;
15
15
  private readonly axes;
@@ -28,7 +28,7 @@ declare class AnchoredIdDeriver {
28
28
  * Creates a new anchor context from a set of anchor column specifications
29
29
  * @param anchors Record of anchor column specifications indexed by anchor ID
30
30
  */
31
- constructor(anchors: Record<string, PColumnSpec>);
31
+ constructor(anchors: Record<string, Pick<PColumnSpec, "axesSpec" | "domain" | "contextDomain">>);
32
32
  /**
33
33
  * Derives an anchored column identifier from a column specification
34
34
  * @param spec Column specification to anchor
@@ -69,7 +69,7 @@ type ResolveAnchorsOptions = {
69
69
  * @param options - Options for resolving anchors
70
70
  * @returns A non-anchored column matcher with all references resolved to actual values
71
71
  */
72
- declare function resolveAnchors(anchors: Record<string, PColumnSpec>, matcher: AnchoredPColumnSelector, options?: ResolveAnchorsOptions): PColumnSelector;
72
+ declare function resolveAnchors(anchors: Record<string, Pick<PColumnSpec, "axesSpec" | "domain" | "contextDomain">>, matcher: AnchoredPColumnSelector, options?: ResolveAnchorsOptions): PColumnSelector;
73
73
  //#endregion
74
74
  export { AnchoredIdDeriver, ResolveAnchorsOptions, resolveAnchors };
75
75
  //# sourceMappingURL=anchored.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"anchored.d.ts","names":[],"sources":["../../../../src/drivers/pframe/spec/anchored.ts"],"mappings":";;;;;;;;AAgCA;;cAAa,iBAAA;EAAA,SAoBiB,OAAA,EAAS,MAAA,SAAe,WAAA;EAAA,iBAnBnC,OAAA;EAAA,iBACA,cAAA;EAAA,iBACA,IAAA;EA0DJ;;;;EAAA,iBArDI,WAAA;EAAA,iBACA,kBAAA;EAgLwB;;;EAAA,iBA5KxB,kBAAA;EAAA,iBACA,yBAAA;EAMoB;;;;cAAT,OAAA,EAAS,MAAA,SAAe,WAAA;EAZnC;;;;;EAqDjB,MAAA,CAAO,IAAA,EAAM,WAAA,GAAc,iBAAA;EAzCyB;;;;;;EAiDpD,MAAA,CAAO,IAAA,EAAM,WAAA,EAAa,WAAA,GAAc,UAAA,KAAe,kBAAA;EAA1C;;;;;;EAoHb,OAAA,CAAQ,IAAA,EAAM,WAAA,EAAa,WAAA,GAAc,UAAA,KAAe,mBAAA;AAAA;;;;KAQ9C,qBAAA;EARiE;AAQ7E;;;EAKE,oBAAA;AAAA;AAYF;;;;;;;;;AAAA,iBAAgB,cAAA,CACd,OAAA,EAAS,MAAA,SAAe,WAAA,GACxB,OAAA,EAAS,uBAAA,EACT,OAAA,GAAU,qBAAA,GACT,eAAA"}
1
+ {"version":3,"file":"anchored.d.ts","names":[],"sources":["../../../../src/drivers/pframe/spec/anchored.ts"],"mappings":";;;;;;;;AAgCA;;cAAa,iBAAA;EAAA,SAqBO,OAAA,EAAS,MAAA,SAEvB,IAAA,CAAK,WAAA;EAAA,iBAtBQ,OAAA;EAAA,iBACA,cAAA;EAAA,iBACA,IAAA;EAoBb;;;;EAAA,iBAfa,WAAA;EAAA,iBACA,kBAAA;EAiEsC;;;EAAA,iBA7DtC,kBAAA;EAAA,iBACA,yBAAA;EAgL0D;;;;cAzKzD,OAAA,EAAS,MAAA,SAEvB,IAAA,CAAK,WAAA;EAtBQ;;;;;EAiEjB,MAAA,CAAO,IAAA,EAAM,WAAA,GAAc,iBAAA;EApDV;;;;;;EA4DjB,MAAA,CAAO,IAAA,EAAM,WAAA,EAAa,WAAA,GAAc,UAAA,KAAe,kBAAA;EAR1C;;;;;;EA4Hb,OAAA,CAAQ,IAAA,EAAM,WAAA,EAAa,WAAA,GAAc,UAAA,KAAe,mBAAA;AAAA;;;;KAQ9C,qBAAA;EAR+B;;;;EAazC,oBAAA;AAAA;;;;;AAYF;;;;;iBAAgB,cAAA,CACd,OAAA,EAAS,MAAA,SAAe,IAAA,CAAK,WAAA,6CAC7B,OAAA,EAAS,uBAAA,EACT,OAAA,GAAU,qBAAA,GACT,eAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"anchored.js","names":[],"sources":["../../../../src/drivers/pframe/spec/anchored.ts"],"sourcesContent":["import canonicalize from \"canonicalize\";\nimport type { AxisFilter, AxisFilterValue } from \"./filtered_column\";\nimport type { SUniversalPColumnId, UniversalPColumnId } from \"./ids\";\nimport { stringifyColumnId } from \"./ids\";\nimport type {\n AAxisSelector,\n AnchorAxisRef,\n AnchorAxisRefByIdx,\n AnchoredPColumnId,\n AnchoredPColumnSelector,\n LegacyAxisSelector,\n PColumnSelector,\n} from \"./selectors\";\nimport type { AxisId, PColumnSpec } from \"./spec\";\nimport { getAxisId, matchAxisId } from \"./spec\";\n\n//\n// Helper functions\n//\n\nfunction axisKey(axis: AxisId): string {\n return canonicalize(getAxisId(axis))!;\n}\n\nfunction domainKey(key: string, value: string): string {\n return JSON.stringify([key, value]);\n}\n\n/**\n * Context for resolving and generating anchored references to columns and axes\n * Maintains maps of known domain values and axes that can be referenced by anchors\n */\nexport class AnchoredIdDeriver {\n private readonly domains = new Map<string, string>();\n private readonly contextDomains = new Map<string, string>();\n private readonly axes = new Map<string, AnchorAxisRefByIdx>();\n /**\n * Domain packs are used to group domain keys that can be anchored to the same anchor\n * This is used to optimize the lookup of domain anchors\n */\n private readonly domainPacks: string[][] = [];\n private readonly contextDomainPacks: string[][] = [];\n /**\n * Maps domain packs to anchors\n */\n private readonly domainPackToAnchor = new Map<string, string>();\n private readonly contextDomainPackToAnchor = new Map<string, string>();\n\n /**\n * Creates a new anchor context from a set of anchor column specifications\n * @param anchors Record of anchor column specifications indexed by anchor ID\n */\n constructor(public readonly anchors: Record<string, PColumnSpec>) {\n const anchorEntries = Object.entries(anchors);\n anchorEntries.sort((a, b) => a[0].localeCompare(b[0]));\n for (const [anchorId, spec] of anchorEntries) {\n for (let axisIdx = 0; axisIdx < spec.axesSpec.length; axisIdx++) {\n const axis = spec.axesSpec[axisIdx];\n const key = axisKey(axis);\n this.axes.set(key, { anchor: anchorId, idx: axisIdx });\n }\n if (spec.domain !== undefined) {\n const domainEntries = Object.entries(spec.domain);\n domainEntries.sort((a, b) => a[0].localeCompare(b[0]));\n\n this.domainPackToAnchor.set(JSON.stringify(domainEntries), anchorId);\n this.domainPacks.push(domainEntries.map(([dKey]) => dKey));\n\n for (const [dKey, dValue] of domainEntries) {\n const key = domainKey(dKey, dValue);\n this.domains.set(key, anchorId);\n }\n }\n if (spec.contextDomain !== undefined) {\n const contextDomainEntries = Object.entries(spec.contextDomain);\n contextDomainEntries.sort((a, b) => a[0].localeCompare(b[0]));\n\n this.contextDomainPackToAnchor.set(JSON.stringify(contextDomainEntries), anchorId);\n this.contextDomainPacks.push(contextDomainEntries.map(([dKey]) => dKey));\n\n for (const [dKey, dValue] of contextDomainEntries) {\n const key = domainKey(dKey, dValue);\n this.contextDomains.set(key, anchorId);\n }\n }\n }\n }\n\n /**\n * Derives an anchored column identifier from a column specification\n * @param spec Column specification to anchor\n * @returns An anchored column identifier that can be used to identify columns similar to the input specification\n */\n derive(spec: PColumnSpec): AnchoredPColumnId;\n\n /**\n * Derives an anchored column identifier from a column specification\n * @param spec Column specification to anchor\n * @param axisFilters Axis filters to apply to the column\n * @returns An anchored and sliced column identifier that can be used to identify columns similar to the input specification\n */\n derive(spec: PColumnSpec, axisFilters?: AxisFilter[]): UniversalPColumnId;\n\n /**\n * Implementation of derive method\n */\n derive(spec: PColumnSpec, axisFilters?: AxisFilter[]): UniversalPColumnId {\n const result: AnchoredPColumnId = {\n name: spec.name,\n axes: [],\n };\n\n let skipDomains: Set<string> | undefined = undefined;\n if (spec.domain !== undefined) {\n outer: for (const domainPack of this.domainPacks) {\n const dAnchor: string[][] = [];\n for (const domainKey of domainPack) {\n const dValue = spec.domain[domainKey];\n if (dValue !== undefined) dAnchor.push([domainKey, dValue]);\n else break outer;\n }\n const domainAnchor = this.domainPackToAnchor.get(JSON.stringify(dAnchor));\n if (domainAnchor !== undefined) {\n result.domainAnchor = domainAnchor;\n skipDomains = new Set(domainPack);\n break;\n }\n }\n }\n\n for (const [dKey, dValue] of Object.entries(spec.domain ?? {})) {\n if (skipDomains !== undefined && skipDomains.has(dKey)) continue;\n const key = domainKey(dKey, dValue);\n const anchorId = this.domains.get(key);\n result.domain ??= {};\n result.domain[dKey] = anchorId ? { anchor: anchorId } : dValue;\n }\n\n let skipContextDomains: Set<string> | undefined = undefined;\n if (spec.contextDomain !== undefined) {\n outer: for (const contextDomainPack of this.contextDomainPacks) {\n const dAnchor: string[][] = [];\n for (const domainKey of contextDomainPack) {\n const dValue = spec.contextDomain[domainKey];\n if (dValue !== undefined) dAnchor.push([domainKey, dValue]);\n else break outer;\n }\n const contextDomainAnchor = this.contextDomainPackToAnchor.get(JSON.stringify(dAnchor));\n if (contextDomainAnchor !== undefined) {\n result.contextDomainAnchor = contextDomainAnchor;\n skipContextDomains = new Set(contextDomainPack);\n break;\n }\n }\n }\n\n for (const [dKey, dValue] of Object.entries(spec.contextDomain ?? {})) {\n if (skipContextDomains !== undefined && skipContextDomains.has(dKey)) continue;\n const key = domainKey(dKey, dValue);\n const anchorId = this.contextDomains.get(key);\n result.contextDomain ??= {};\n result.contextDomain[dKey] = anchorId ? { anchor: anchorId } : dValue;\n }\n\n result.axes = spec.axesSpec.map((axis) => {\n const key = axisKey(axis);\n const anchorAxisRef = this.axes.get(key);\n if (anchorAxisRef === undefined) return getAxisId(axis);\n else return anchorAxisRef;\n });\n\n // If no axis filters are provided, return the anchored ID as is\n if (!axisFilters || axisFilters.length === 0) {\n return result;\n }\n\n // Process axis filters and create a sliced column ID\n const resolvedFilters: [number, AxisFilterValue][] = [];\n\n for (const filter of axisFilters) {\n const [axisIdOrIndex, value] = filter;\n\n // If it's already a numeric index, validate it\n if (typeof axisIdOrIndex === \"number\") {\n if (axisIdOrIndex < 0 || axisIdOrIndex >= spec.axesSpec.length) {\n throw new Error(\n `Axis index ${axisIdOrIndex} is out of bounds (0-${spec.axesSpec.length - 1})`,\n );\n }\n resolvedFilters.push([axisIdOrIndex, value]);\n } else {\n // If it's a string (axis name), resolve it to an index\n const axisIndex = spec.axesSpec.findIndex((axis) => axis.name === axisIdOrIndex);\n if (axisIndex === -1) {\n throw new Error(\n `Axis with name \"${axisIdOrIndex}\" not found in the column specification`,\n );\n }\n resolvedFilters.push([axisIndex, value]);\n }\n }\n\n // Sort filters by axis index to ensure consistency\n resolvedFilters.sort((a, b) => a[0] - b[0]);\n\n return {\n source: result,\n axisFilters: resolvedFilters,\n };\n }\n\n /**\n * Derives a canonicalized string representation of an anchored column identifier, can be used as a unique identifier for the column\n * @param spec Column specification to anchor\n * @param axisFilters Optional axis filters to apply to the column\n * @returns A canonicalized string representation of the anchored column identifier\n */\n deriveS(spec: PColumnSpec, axisFilters?: AxisFilter[]): SUniversalPColumnId {\n return stringifyColumnId(this.derive(spec, axisFilters));\n }\n}\n\n/**\n * Options for the resolveAnchors function\n */\nexport type ResolveAnchorsOptions = {\n /**\n * If true, missing domain keys in anchors will be ignored.\n * If false (default), an error will be thrown.\n */\n ignoreMissingDomains?: boolean;\n};\n\n/**\n * Resolves anchored references in a column matcher to create a non-anchored matcher.\n * Doing an opposite operation to {@link AnchorIdDeriver.derive()}.\n *\n * @param anchors - Record of anchor column specifications indexed by anchor id\n * @param matcher - An anchored column matcher (or id, which is subtype of it) containing references that need to be resolved\n * @param options - Options for resolving anchors\n * @returns A non-anchored column matcher with all references resolved to actual values\n */\nexport function resolveAnchors(\n anchors: Record<string, PColumnSpec>,\n matcher: AnchoredPColumnSelector,\n options?: ResolveAnchorsOptions,\n): PColumnSelector {\n const result = { ...matcher };\n const ignoreMissingDomains = options?.ignoreMissingDomains ?? false;\n\n if (result.domainAnchor !== undefined) {\n const anchorSpec = anchors[result.domainAnchor];\n if (!anchorSpec) throw new Error(`Anchor \"${result.domainAnchor}\" not found`);\n\n const anchorDomains = anchorSpec.domain || {};\n result.domain = { ...anchorDomains, ...result.domain };\n delete result.domainAnchor;\n }\n\n if (result.domain) {\n const resolvedDomain: Record<string, string> = {};\n for (const [key, value] of Object.entries(result.domain)) {\n if (typeof value === \"string\") {\n resolvedDomain[key] = value;\n } else {\n // It's an AnchorDomainRef\n const anchorSpec = anchors[value.anchor];\n if (!anchorSpec)\n throw new Error(`Anchor \"${value.anchor}\" not found for domain key \"${key}\"`);\n\n if (!anchorSpec.domain || anchorSpec.domain[key] === undefined) {\n if (!ignoreMissingDomains)\n throw new Error(`Domain key \"${key}\" not found in anchor \"${value.anchor}\"`);\n continue;\n }\n\n resolvedDomain[key] = anchorSpec.domain[key];\n }\n }\n result.domain = resolvedDomain;\n }\n\n if (result.contextDomainAnchor !== undefined) {\n const anchorSpec = anchors[result.contextDomainAnchor];\n if (!anchorSpec) throw new Error(`Anchor \"${result.contextDomainAnchor}\" not found`);\n\n const anchorContextDomains = anchorSpec.contextDomain || {};\n result.contextDomain = { ...anchorContextDomains, ...result.contextDomain };\n delete result.contextDomainAnchor;\n }\n\n if (result.contextDomain) {\n const resolvedContextDomain: Record<string, string> = {};\n for (const [key, value] of Object.entries(result.contextDomain)) {\n if (typeof value === \"string\") {\n resolvedContextDomain[key] = value;\n } else {\n // It's an AnchorDomainRef\n const anchorSpec = anchors[value.anchor];\n if (!anchorSpec)\n throw new Error(`Anchor \"${value.anchor}\" not found for contextDomain key \"${key}\"`);\n\n if (!anchorSpec.contextDomain || anchorSpec.contextDomain[key] === undefined) {\n if (!ignoreMissingDomains)\n throw new Error(`Context domain key \"${key}\" not found in anchor \"${value.anchor}\"`);\n continue;\n }\n\n resolvedContextDomain[key] = anchorSpec.contextDomain[key];\n }\n }\n result.contextDomain = resolvedContextDomain;\n }\n\n if (result.axes) result.axes = result.axes.map((axis) => resolveAxisReference(anchors, axis));\n\n return result as PColumnSelector;\n}\n\n/**\n * Resolves an anchored axis reference to a concrete AxisId\n */\nfunction resolveAxisReference(\n anchors: Record<string, PColumnSpec>,\n axisRef: AAxisSelector,\n): LegacyAxisSelector {\n if (!isAnchorAxisRef(axisRef)) return axisRef;\n\n // It's an anchored reference\n const anchorId = axisRef.anchor;\n const anchorSpec = anchors[anchorId];\n if (!anchorSpec) throw new Error(`Anchor \"${anchorId}\" not found for axis reference`);\n\n if (\"idx\" in axisRef) {\n // AnchorAxisRefByIdx\n if (axisRef.idx < 0 || axisRef.idx >= anchorSpec.axesSpec.length)\n throw new Error(`Axis index ${axisRef.idx} out of bounds for anchor \"${anchorId}\"`);\n return anchorSpec.axesSpec[axisRef.idx];\n } else if (\"name\" in axisRef) {\n // AnchorAxisRefByName\n const matches = anchorSpec.axesSpec.filter((axis) => axis.name === axisRef.name);\n if (matches.length > 1)\n throw new Error(`Multiple axes with name \"${axisRef.name}\" found in anchor \"${anchorId}\"`);\n if (matches.length === 0)\n throw new Error(`Axis with name \"${axisRef.name}\" not found in anchor \"${anchorId}\"`);\n return matches[0];\n } else if (\"id\" in axisRef) {\n // AnchorAxisRefByMatcher\n const matches = anchorSpec.axesSpec.filter((axis) => matchAxisId(axisRef.id, getAxisId(axis)));\n if (matches.length > 1)\n throw new Error(`Multiple matching axes found for matcher in anchor \"${anchorId}\"`);\n if (matches.length === 0)\n throw new Error(`No matching axis found for matcher in anchor \"${anchorId}\"`);\n return matches[0];\n }\n\n throw new Error(`Unsupported axis reference type`);\n}\n\n/**\n * Type guard to check if a value is an anchored axis reference\n */\nfunction isAnchorAxisRef(value: AAxisSelector): value is AnchorAxisRef {\n return typeof value === \"object\" && \"anchor\" in value;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"anchored.js","names":[],"sources":["../../../../src/drivers/pframe/spec/anchored.ts"],"sourcesContent":["import canonicalize from \"canonicalize\";\nimport type { AxisFilter, AxisFilterValue } from \"./filtered_column\";\nimport type { SUniversalPColumnId, UniversalPColumnId } from \"./ids\";\nimport { stringifyColumnId } from \"./ids\";\nimport type {\n AAxisSelector,\n AnchorAxisRef,\n AnchorAxisRefByIdx,\n AnchoredPColumnId,\n AnchoredPColumnSelector,\n LegacyAxisSelector,\n PColumnSelector,\n} from \"./selectors\";\nimport type { AxisId, PColumnSpec } from \"./spec\";\nimport { getAxisId, matchAxisId } from \"./spec\";\n\n//\n// Helper functions\n//\n\nfunction axisKey(axis: AxisId): string {\n return canonicalize(getAxisId(axis))!;\n}\n\nfunction domainKey(key: string, value: string): string {\n return JSON.stringify([key, value]);\n}\n\n/**\n * Context for resolving and generating anchored references to columns and axes\n * Maintains maps of known domain values and axes that can be referenced by anchors\n */\nexport class AnchoredIdDeriver {\n private readonly domains = new Map<string, string>();\n private readonly contextDomains = new Map<string, string>();\n private readonly axes = new Map<string, AnchorAxisRefByIdx>();\n /**\n * Domain packs are used to group domain keys that can be anchored to the same anchor\n * This is used to optimize the lookup of domain anchors\n */\n private readonly domainPacks: string[][] = [];\n private readonly contextDomainPacks: string[][] = [];\n /**\n * Maps domain packs to anchors\n */\n private readonly domainPackToAnchor = new Map<string, string>();\n private readonly contextDomainPackToAnchor = new Map<string, string>();\n\n /**\n * Creates a new anchor context from a set of anchor column specifications\n * @param anchors Record of anchor column specifications indexed by anchor ID\n */\n constructor(\n public readonly anchors: Record<\n string,\n Pick<PColumnSpec, \"axesSpec\" | \"domain\" | \"contextDomain\">\n >,\n ) {\n const anchorEntries = Object.entries(anchors);\n anchorEntries.sort((a, b) => a[0].localeCompare(b[0]));\n for (const [anchorId, spec] of anchorEntries) {\n for (let axisIdx = 0; axisIdx < spec.axesSpec.length; axisIdx++) {\n const axis = spec.axesSpec[axisIdx];\n const key = axisKey(axis);\n this.axes.set(key, { anchor: anchorId, idx: axisIdx });\n }\n if (spec.domain !== undefined) {\n const domainEntries = Object.entries(spec.domain);\n domainEntries.sort((a, b) => a[0].localeCompare(b[0]));\n\n this.domainPackToAnchor.set(JSON.stringify(domainEntries), anchorId);\n this.domainPacks.push(domainEntries.map(([dKey]) => dKey));\n\n for (const [dKey, dValue] of domainEntries) {\n const key = domainKey(dKey, dValue);\n this.domains.set(key, anchorId);\n }\n }\n if (spec.contextDomain !== undefined) {\n const contextDomainEntries = Object.entries(spec.contextDomain);\n contextDomainEntries.sort((a, b) => a[0].localeCompare(b[0]));\n\n this.contextDomainPackToAnchor.set(JSON.stringify(contextDomainEntries), anchorId);\n this.contextDomainPacks.push(contextDomainEntries.map(([dKey]) => dKey));\n\n for (const [dKey, dValue] of contextDomainEntries) {\n const key = domainKey(dKey, dValue);\n this.contextDomains.set(key, anchorId);\n }\n }\n }\n }\n\n /**\n * Derives an anchored column identifier from a column specification\n * @param spec Column specification to anchor\n * @returns An anchored column identifier that can be used to identify columns similar to the input specification\n */\n derive(spec: PColumnSpec): AnchoredPColumnId;\n\n /**\n * Derives an anchored column identifier from a column specification\n * @param spec Column specification to anchor\n * @param axisFilters Axis filters to apply to the column\n * @returns An anchored and sliced column identifier that can be used to identify columns similar to the input specification\n */\n derive(spec: PColumnSpec, axisFilters?: AxisFilter[]): UniversalPColumnId;\n\n /**\n * Implementation of derive method\n */\n derive(spec: PColumnSpec, axisFilters?: AxisFilter[]): UniversalPColumnId {\n const result: AnchoredPColumnId = {\n name: spec.name,\n axes: [],\n };\n\n let skipDomains: Set<string> | undefined = undefined;\n if (spec.domain !== undefined) {\n outer: for (const domainPack of this.domainPacks) {\n const dAnchor: string[][] = [];\n for (const domainKey of domainPack) {\n const dValue = spec.domain[domainKey];\n if (dValue !== undefined) dAnchor.push([domainKey, dValue]);\n else break outer;\n }\n const domainAnchor = this.domainPackToAnchor.get(JSON.stringify(dAnchor));\n if (domainAnchor !== undefined) {\n result.domainAnchor = domainAnchor;\n skipDomains = new Set(domainPack);\n break;\n }\n }\n }\n\n for (const [dKey, dValue] of Object.entries(spec.domain ?? {})) {\n if (skipDomains !== undefined && skipDomains.has(dKey)) continue;\n const key = domainKey(dKey, dValue);\n const anchorId = this.domains.get(key);\n result.domain ??= {};\n result.domain[dKey] = anchorId ? { anchor: anchorId } : dValue;\n }\n\n let skipContextDomains: Set<string> | undefined = undefined;\n if (spec.contextDomain !== undefined) {\n outer: for (const contextDomainPack of this.contextDomainPacks) {\n const dAnchor: string[][] = [];\n for (const domainKey of contextDomainPack) {\n const dValue = spec.contextDomain[domainKey];\n if (dValue !== undefined) dAnchor.push([domainKey, dValue]);\n else break outer;\n }\n const contextDomainAnchor = this.contextDomainPackToAnchor.get(JSON.stringify(dAnchor));\n if (contextDomainAnchor !== undefined) {\n result.contextDomainAnchor = contextDomainAnchor;\n skipContextDomains = new Set(contextDomainPack);\n break;\n }\n }\n }\n\n for (const [dKey, dValue] of Object.entries(spec.contextDomain ?? {})) {\n if (skipContextDomains !== undefined && skipContextDomains.has(dKey)) continue;\n const key = domainKey(dKey, dValue);\n const anchorId = this.contextDomains.get(key);\n result.contextDomain ??= {};\n result.contextDomain[dKey] = anchorId ? { anchor: anchorId } : dValue;\n }\n\n result.axes = spec.axesSpec.map((axis) => {\n const key = axisKey(axis);\n const anchorAxisRef = this.axes.get(key);\n if (anchorAxisRef === undefined) return getAxisId(axis);\n else return anchorAxisRef;\n });\n\n // If no axis filters are provided, return the anchored ID as is\n if (!axisFilters || axisFilters.length === 0) {\n return result;\n }\n\n // Process axis filters and create a sliced column ID\n const resolvedFilters: [number, AxisFilterValue][] = [];\n\n for (const filter of axisFilters) {\n const [axisIdOrIndex, value] = filter;\n\n // If it's already a numeric index, validate it\n if (typeof axisIdOrIndex === \"number\") {\n if (axisIdOrIndex < 0 || axisIdOrIndex >= spec.axesSpec.length) {\n throw new Error(\n `Axis index ${axisIdOrIndex} is out of bounds (0-${spec.axesSpec.length - 1})`,\n );\n }\n resolvedFilters.push([axisIdOrIndex, value]);\n } else {\n // If it's a string (axis name), resolve it to an index\n const axisIndex = spec.axesSpec.findIndex((axis) => axis.name === axisIdOrIndex);\n if (axisIndex === -1) {\n throw new Error(\n `Axis with name \"${axisIdOrIndex}\" not found in the column specification`,\n );\n }\n resolvedFilters.push([axisIndex, value]);\n }\n }\n\n // Sort filters by axis index to ensure consistency\n resolvedFilters.sort((a, b) => a[0] - b[0]);\n\n return {\n source: result,\n axisFilters: resolvedFilters,\n };\n }\n\n /**\n * Derives a canonicalized string representation of an anchored column identifier, can be used as a unique identifier for the column\n * @param spec Column specification to anchor\n * @param axisFilters Optional axis filters to apply to the column\n * @returns A canonicalized string representation of the anchored column identifier\n */\n deriveS(spec: PColumnSpec, axisFilters?: AxisFilter[]): SUniversalPColumnId {\n return stringifyColumnId(this.derive(spec, axisFilters));\n }\n}\n\n/**\n * Options for the resolveAnchors function\n */\nexport type ResolveAnchorsOptions = {\n /**\n * If true, missing domain keys in anchors will be ignored.\n * If false (default), an error will be thrown.\n */\n ignoreMissingDomains?: boolean;\n};\n\n/**\n * Resolves anchored references in a column matcher to create a non-anchored matcher.\n * Doing an opposite operation to {@link AnchorIdDeriver.derive()}.\n *\n * @param anchors - Record of anchor column specifications indexed by anchor id\n * @param matcher - An anchored column matcher (or id, which is subtype of it) containing references that need to be resolved\n * @param options - Options for resolving anchors\n * @returns A non-anchored column matcher with all references resolved to actual values\n */\nexport function resolveAnchors(\n anchors: Record<string, Pick<PColumnSpec, \"axesSpec\" | \"domain\" | \"contextDomain\">>,\n matcher: AnchoredPColumnSelector,\n options?: ResolveAnchorsOptions,\n): PColumnSelector {\n const result = { ...matcher };\n const ignoreMissingDomains = options?.ignoreMissingDomains ?? false;\n\n if (result.domainAnchor !== undefined) {\n const anchorSpec = anchors[result.domainAnchor];\n if (!anchorSpec) throw new Error(`Anchor \"${result.domainAnchor}\" not found`);\n\n const anchorDomains = anchorSpec.domain || {};\n result.domain = { ...anchorDomains, ...result.domain };\n delete result.domainAnchor;\n }\n\n if (result.domain) {\n const resolvedDomain: Record<string, string> = {};\n for (const [key, value] of Object.entries(result.domain)) {\n if (typeof value === \"string\") {\n resolvedDomain[key] = value;\n } else {\n // It's an AnchorDomainRef\n const anchorSpec = anchors[value.anchor];\n if (!anchorSpec)\n throw new Error(`Anchor \"${value.anchor}\" not found for domain key \"${key}\"`);\n\n if (!anchorSpec.domain || anchorSpec.domain[key] === undefined) {\n if (!ignoreMissingDomains)\n throw new Error(`Domain key \"${key}\" not found in anchor \"${value.anchor}\"`);\n continue;\n }\n\n resolvedDomain[key] = anchorSpec.domain[key];\n }\n }\n result.domain = resolvedDomain;\n }\n\n if (result.contextDomainAnchor !== undefined) {\n const anchorSpec = anchors[result.contextDomainAnchor];\n if (!anchorSpec) throw new Error(`Anchor \"${result.contextDomainAnchor}\" not found`);\n\n const anchorContextDomains = anchorSpec.contextDomain || {};\n result.contextDomain = { ...anchorContextDomains, ...result.contextDomain };\n delete result.contextDomainAnchor;\n }\n\n if (result.contextDomain) {\n const resolvedContextDomain: Record<string, string> = {};\n for (const [key, value] of Object.entries(result.contextDomain)) {\n if (typeof value === \"string\") {\n resolvedContextDomain[key] = value;\n } else {\n // It's an AnchorDomainRef\n const anchorSpec = anchors[value.anchor];\n if (!anchorSpec)\n throw new Error(`Anchor \"${value.anchor}\" not found for contextDomain key \"${key}\"`);\n\n if (!anchorSpec.contextDomain || anchorSpec.contextDomain[key] === undefined) {\n if (!ignoreMissingDomains)\n throw new Error(`Context domain key \"${key}\" not found in anchor \"${value.anchor}\"`);\n continue;\n }\n\n resolvedContextDomain[key] = anchorSpec.contextDomain[key];\n }\n }\n result.contextDomain = resolvedContextDomain;\n }\n\n if (result.axes) result.axes = result.axes.map((axis) => resolveAxisReference(anchors, axis));\n\n return result as PColumnSelector;\n}\n\n/**\n * Resolves an anchored axis reference to a concrete AxisId\n */\nfunction resolveAxisReference(\n anchors: Record<string, Pick<PColumnSpec, \"axesSpec\">>,\n axisRef: AAxisSelector,\n): LegacyAxisSelector {\n if (!isAnchorAxisRef(axisRef)) return axisRef;\n\n // It's an anchored reference\n const anchorId = axisRef.anchor;\n const anchorSpec = anchors[anchorId];\n if (!anchorSpec) throw new Error(`Anchor \"${anchorId}\" not found for axis reference`);\n\n if (\"idx\" in axisRef) {\n // AnchorAxisRefByIdx\n if (axisRef.idx < 0 || axisRef.idx >= anchorSpec.axesSpec.length)\n throw new Error(`Axis index ${axisRef.idx} out of bounds for anchor \"${anchorId}\"`);\n return anchorSpec.axesSpec[axisRef.idx];\n } else if (\"name\" in axisRef) {\n // AnchorAxisRefByName\n const matches = anchorSpec.axesSpec.filter((axis) => axis.name === axisRef.name);\n if (matches.length > 1)\n throw new Error(`Multiple axes with name \"${axisRef.name}\" found in anchor \"${anchorId}\"`);\n if (matches.length === 0)\n throw new Error(`Axis with name \"${axisRef.name}\" not found in anchor \"${anchorId}\"`);\n return matches[0];\n } else if (\"id\" in axisRef) {\n // AnchorAxisRefByMatcher\n const matches = anchorSpec.axesSpec.filter((axis) => matchAxisId(axisRef.id, getAxisId(axis)));\n if (matches.length > 1)\n throw new Error(`Multiple matching axes found for matcher in anchor \"${anchorId}\"`);\n if (matches.length === 0)\n throw new Error(`No matching axis found for matcher in anchor \"${anchorId}\"`);\n return matches[0];\n }\n\n throw new Error(`Unsupported axis reference type`);\n}\n\n/**\n * Type guard to check if a value is an anchored axis reference\n */\nfunction isAnchorAxisRef(value: AAxisSelector): value is AnchorAxisRef {\n return typeof value === \"object\" && \"anchor\" in value;\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Annotation, AnnotationJson, AxesId, AxesSpec, AxisId, AxisSpec, AxisSpecNormalized, AxisTree, AxisValueType, ColumnValueType, Domain, DomainJson, Metadata, MetadataJson, PAxisName, PColumn, PColumnIdAndSpec, PColumnInfo, PColumnLazy, PColumnName, PColumnSpec, PColumnSpecId, PDataColumnSpec, PUniversalColumnSpec, ValueType, canonicalizeAxisId, canonicalizeAxisWithParents, getArrayFromAxisTree, getAxesId, getAxesTree, getAxisId, getColumnIdAndSpec, getDenormalizedAxesList, getNormalizedAxesList, getPColumnSpecId, getSetFromAxisTree, getTypeFromPColumnOrAxisSpec, isAxisId, isLabelColumn, isLinkerColumn, matchAxisId, readAnnotation, readAnnotationJson, readAnnotationJsonOrThrow, readDomain, readDomainJson, readDomainJsonOrThrow, readMetadata, readMetadataJson, readMetadataJsonOrThrow, resolveAnnotationParents } from "./spec.js";
1
+ import { Annotation, AnnotationJson, AxesId, AxesSpec, AxisId, AxisSpec, AxisSpecNormalized, AxisTree, AxisValueType, ColumnValueType, Domain, DomainJson, Metadata, MetadataJson, PAxisName, PColumn, PColumnIdAndSpec, PColumnInfo, PColumnLazy, PColumnName, PColumnSpec, PColumnSpecId, PDataColumnSpec, PUniversalColumnSpec, Trace, TraceEntry, ValueType, canonicalizeAxisId, canonicalizeAxisWithParents, getArrayFromAxisTree, getAxesId, getAxesTree, getAxisId, getColumnIdAndSpec, getDenormalizedAxesList, getNormalizedAxesList, getPColumnSpecId, getSetFromAxisTree, getTypeFromPColumnOrAxisSpec, isAxisId, isLabelColumn, isLinkerColumn, matchAxisId, readAnnotation, readAnnotationJson, readAnnotationJsonOrThrow, readDomain, readDomainJson, readDomainJsonOrThrow, readMetadata, readMetadataJson, readMetadataJsonOrThrow, resolveAnnotationParents } from "./spec.js";
2
2
  import { AAxisSelector, ADomain, AnchorAxisIdOrRefBasic, AnchorAxisRef, AnchorAxisRefByIdx, AnchorAxisRefByMatcher, AnchorAxisRefByName, AnchorDomainRef, AnchoredColumnMatchStrategy, AnchoredPColumnId, AnchoredPColumnSelector, LegacyAxisSelector, PColumnSelector, SingleAxisSelector, isAnchoredPColumnId, legacyColumnSelectorsToPredicate, matchAxis, matchPColumn } from "./selectors.js";
3
3
  import { AxisFilter, AxisFilterByIdx, AxisFilterByName, AxisFilterValue, FilteredPColumn, FilteredPColumnId, isFilteredPColumn } from "./filtered_column.js";
4
4
  import { SUniversalPColumnId, UniversalPColumnId, parseColumnId, stringifyColumnId } from "./ids.js";
@@ -77,6 +77,7 @@ const Annotation = {
77
77
  IsScore: "pl7.app/isScore",
78
78
  IsSubset: "pl7.app/isSubset",
79
79
  Label: "pl7.app/label",
80
+ LinkLabel: "pl7.app/linkLabel",
80
81
  Max: "pl7.app/max",
81
82
  Min: "pl7.app/min",
82
83
  MultipliesBy: "pl7.app/multipliesBy",
@@ -100,6 +101,10 @@ const Annotation = {
100
101
  IsMainSequence: "pl7.app/vdj/isMainSequence"
101
102
  }
102
103
  };
104
+ const TraceEntrySchema = zod.z.object({
105
+ type: zod.z.string(),
106
+ label: zod.z.string()
107
+ }).catchall(zod.z.unknown());
103
108
  const ValueTypeSchema = zod.z.enum([
104
109
  "Int",
105
110
  "Long",
@@ -139,7 +144,7 @@ const AnnotationJson = {
139
144
  [Annotation.Sequence.Annotation.Mapping]: zod.z.record(zod.z.string(), zod.z.string()),
140
145
  [Annotation.Sequence.IsAnnotation]: zod.z.boolean(),
141
146
  [Annotation.Table.OrderPriority]: zod.z.number(),
142
- [Annotation.Trace]: zod.z.record(zod.z.string(), zod.z.unknown()),
147
+ [Annotation.Trace]: zod.z.array(TraceEntrySchema),
143
148
  [Annotation.VDJ.IsAssemblingFeature]: zod.z.boolean()
144
149
  };
145
150
  function readAnnotation(spec, key) {
@@ -282,9 +287,9 @@ function getNormalizedAxesList(axes) {
282
287
  }
283
288
  /** Create list of regular axisSpec from normalized (parents are indexes, inside of current axes list) */
284
289
  function getDenormalizedAxesList(axesSpec) {
285
- const idsList = axesSpec.map((axisSpec) => require_json.canonicalizeJson(getAxisId(axisSpec)));
290
+ const idsList = axesSpec.map(canonicalizeAxisId);
286
291
  return axesSpec.map((axisSpec) => {
287
- const parentIdxs = axisSpec.parentAxesSpec.map((axisSpec) => require_json.canonicalizeJson(getAxisId(axisSpec))).map((id) => idsList.indexOf(id));
292
+ const parentIdxs = axisSpec.parentAxesSpec.map(canonicalizeAxisId).map((id) => idsList.indexOf(id));
288
293
  const { parentAxesSpec: _, ...copiedRest } = axisSpec;
289
294
  if (parentIdxs.length) return {
290
295
  ...copiedRest,
@@ -1 +1 @@
1
- {"version":3,"file":"spec.cjs","names":["ensureError","z","canonicalizeJson"],"sources":["../../../../src/drivers/pframe/spec/spec.ts"],"sourcesContent":["import { ensureError } from \"../../../errors\";\nimport { canonicalizeJson, type CanonicalizedJson, type StringifiedJson } from \"../../../json\";\nimport type { PObject, PObjectId, PObjectSpec } from \"../../../pool\";\nimport { z } from \"zod\";\n\nexport const ValueType = {\n Int: \"Int\",\n Long: \"Long\",\n Float: \"Float\",\n Double: \"Double\",\n String: \"String\",\n Bytes: \"Bytes\",\n} as const;\n\nexport type AxisValueType = Extract<ValueType, \"Int\" | \"Long\" | \"String\">;\nexport type ColumnValueType = ValueType;\n\n/** PFrame columns and axes within them may store one of these types. */\nexport type ValueType = (typeof ValueType)[keyof typeof ValueType];\n\nexport type Metadata = Record<string, string>;\n\nexport function readMetadata<U extends Metadata, T extends keyof U = keyof U>(\n metadata: Metadata | undefined,\n key: T,\n): U[T] | undefined {\n return (metadata as U | undefined)?.[key];\n}\n\ntype MetadataJsonImpl<M> = {\n [P in keyof M as M[P] extends StringifiedJson ? P : never]: M[P] extends StringifiedJson<infer U>\n ? z.ZodType<U>\n : never;\n};\nexport type MetadataJson<M> = MetadataJsonImpl<Required<M>>;\n\nexport function readMetadataJsonOrThrow<M extends Metadata, T extends keyof MetadataJson<M>>(\n metadata: Metadata | undefined,\n metadataJson: MetadataJson<M>,\n key: T,\n methodNameInError: string = \"readMetadataJsonOrThrow\",\n): z.infer<MetadataJson<M>[T]> | undefined {\n const json = readMetadata<M, T>(metadata, key);\n if (json === undefined) return undefined;\n\n const schema = metadataJson[key];\n try {\n const value = JSON.parse(json);\n return schema.parse(value);\n } catch (error: unknown) {\n throw new Error(\n `${methodNameInError} failed, ` +\n `key: ${String(key)}, ` +\n `value: ${json}, ` +\n `error: ${ensureError(error)}`,\n );\n }\n}\n\nexport function readMetadataJson<M extends Metadata, T extends keyof MetadataJson<M>>(\n metadata: Metadata | undefined,\n metadataJson: MetadataJson<M>,\n key: T,\n): z.infer<MetadataJson<M>[T]> | undefined {\n try {\n return readMetadataJsonOrThrow(metadata, metadataJson, key);\n } catch {\n return undefined; // treat invalid values as unset\n }\n}\n\n/// Well-known domains\nexport const Domain = {\n Alphabet: \"pl7.app/alphabet\",\n BlockId: \"pl7.app/blockId\",\n VDJ: {\n Clustering: {\n BlockId: \"pl7.app/vdj/clustering/blockId\",\n },\n ScClonotypeChain: {\n Index: \"pl7.app/vdj/scClonotypeChain/index\",\n },\n },\n} as const;\n\nexport type Domain = Metadata &\n Partial<{\n [Domain.Alphabet]: \"nucleotide\" | \"aminoacid\" | (string & {});\n [Domain.BlockId]: string;\n [Domain.VDJ.ScClonotypeChain.Index]: \"primary\" | \"secondary\" | (string & {});\n }>;\n\nexport type DomainJson = MetadataJson<Domain>;\nexport const DomainJson: DomainJson = {};\n\n/// Helper function for reading plain domain values\nexport function readDomain<T extends keyof Domain>(\n spec: { domain?: Metadata | undefined } | undefined,\n key: T,\n): Domain[T] | undefined {\n return readMetadata<Domain, T>(spec?.domain, key);\n}\n\n/// Helper function for reading json-encoded domain values, throws on JSON parsing error\nexport function readDomainJsonOrThrow<T extends keyof DomainJson>(\n spec: { domain?: Metadata | undefined } | undefined,\n key: T,\n): z.infer<DomainJson[T]> | undefined {\n return readMetadataJsonOrThrow<Domain, T>(spec?.domain, DomainJson, key, \"readDomainJsonOrThrow\");\n}\n\n/// Helper function for reading json-encoded domain values, returns undefined on JSON parsing error\nexport function readDomainJson<T extends keyof DomainJson>(\n spec: { domain?: Metadata | undefined } | undefined,\n key: T,\n): z.infer<DomainJson[T]> | undefined {\n return readMetadataJson<Domain, T>(spec?.domain, DomainJson, key);\n}\n\n/// Well-known annotations\nexport const Annotation = {\n AxisNature: \"pl7.app/axisNature\",\n Alphabet: \"pl7.app/alphabet\",\n Description: \"pl7.app/description\",\n DiscreteValues: \"pl7.app/discreteValues\",\n Format: \"pl7.app/format\",\n Graph: {\n Axis: {\n HighCardinality: \"pl7.app/graph/axis/highCardinality\",\n LowerLimit: \"pl7.app/graph/axis/lowerLimit\",\n SymmetricRange: \"pl7.app/graph/axis/symmetricRange\",\n UpperLimit: \"pl7.app/graph/axis/upperLimit\",\n },\n IsDenseAxis: \"pl7.app/graph/isDenseAxis\",\n IsVirtual: \"pl7.app/graph/isVirtual\",\n Palette: \"pl7.app/graph/palette\",\n Thresholds: \"pl7.app/graph/thresholds\",\n TreatAbsentValuesAs: \"pl7.app/graph/treatAbsentValuesAs\",\n },\n HideDataFromUi: \"pl7.app/hideDataFromUi\",\n HideDataFromGraphs: \"pl7.app/hideDataFromGraphs\",\n IsDiscreteFilter: \"pl7.app/isDiscreteFilter\",\n IsAnchor: \"pl7.app/isAnchor\",\n IsLinkerColumn: \"pl7.app/isLinkerColumn\",\n IsScore: \"pl7.app/isScore\",\n IsSubset: \"pl7.app/isSubset\",\n Label: \"pl7.app/label\",\n Max: \"pl7.app/max\",\n Min: \"pl7.app/min\",\n MultipliesBy: \"pl7.app/multipliesBy\",\n Parents: \"pl7.app/parents\",\n Score: {\n DefaultCutoff: \"pl7.app/score/defaultCutoff\",\n RankingOrder: \"pl7.app/score/rankingOrder\",\n },\n Sequence: {\n Annotation: {\n Mapping: \"pl7.app/sequence/annotation/mapping\",\n },\n IsAnnotation: \"pl7.app/sequence/isAnnotation\",\n },\n Table: {\n FontFamily: \"pl7.app/table/fontFamily\",\n OrderPriority: \"pl7.app/table/orderPriority\",\n Visibility: \"pl7.app/table/visibility\",\n },\n Trace: \"pl7.app/trace\",\n VDJ: {\n IsAssemblingFeature: \"pl7.app/vdj/isAssemblingFeature\",\n IsMainSequence: \"pl7.app/vdj/isMainSequence\",\n },\n} as const;\n\nexport type Annotation = Metadata &\n Partial<{\n [Annotation.Alphabet]: \"nucleotide\" | \"aminoacid\" | (string & {});\n [Annotation.AxisNature]: \"homogeneous\" | \"heterogeneous\" | \"scaleCompatible\" | (string & {});\n [Annotation.Description]: string;\n [Annotation.DiscreteValues]: StringifiedJson<number[]> | StringifiedJson<string[]>;\n [Annotation.Format]: string;\n [Annotation.Graph.Axis.HighCardinality]: StringifiedJson<boolean>;\n [Annotation.Graph.Axis.LowerLimit]: StringifiedJson<number>;\n [Annotation.Graph.Axis.SymmetricRange]: StringifiedJson<boolean>;\n [Annotation.Graph.Axis.UpperLimit]: StringifiedJson<number>;\n [Annotation.Graph.IsDenseAxis]: StringifiedJson<boolean>;\n [Annotation.Graph.IsVirtual]: StringifiedJson<boolean>;\n [Annotation.Graph.Palette]: StringifiedJson<{ mapping: Record<string, number>; name: string }>;\n [Annotation.Graph.Thresholds]: StringifiedJson<\n { columnId: { valueType: ValueType; name: string }; value: number }[]\n >;\n [Annotation.Graph.TreatAbsentValuesAs]: StringifiedJson<number>;\n [Annotation.HideDataFromGraphs]: StringifiedJson<boolean>;\n [Annotation.HideDataFromUi]: StringifiedJson<boolean>;\n [Annotation.IsDiscreteFilter]: StringifiedJson<boolean>;\n [Annotation.IsLinkerColumn]: StringifiedJson<boolean>;\n [Annotation.IsSubset]: StringifiedJson<boolean>;\n [Annotation.Label]: string;\n [Annotation.Max]: StringifiedJson<number>;\n [Annotation.Min]: StringifiedJson<number>;\n [Annotation.MultipliesBy]: StringifiedJson<AxisSpec[\"name\"][]>;\n [Annotation.Parents]: StringifiedJson<AxisSpec[\"name\"][]>;\n [Annotation.Sequence.Annotation.Mapping]: StringifiedJson<Record<string, string>>;\n [Annotation.Sequence.IsAnnotation]: StringifiedJson<boolean>;\n [Annotation.Table.FontFamily]: string;\n [Annotation.Table.OrderPriority]: StringifiedJson<number>;\n [Annotation.Table.Visibility]: \"hidden\" | \"optional\" | (string & {});\n [Annotation.Trace]: StringifiedJson<Record<string, unknown>>;\n [Annotation.VDJ.IsAssemblingFeature]: StringifiedJson<boolean>;\n }>;\n\n// export const AxisSpec = z.object({\n// type: z.nativeEnum(ValueType),\n// name: z.string(),\n// domain: z.record(z.string(), z.string()).optional(),\n// annotations: z.record(z.string(), z.string()).optional(),\n// parentAxes: z.array(z.number()).optional(),\n// }).passthrough();\n//\n// type Expect<T extends true> = T;\n// type Equal<X, Y> =\n// (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false;\n//\n// type _test = Expect<Equal<\n// Readonly<z.infer<typeof AxisSpec>>,\n// Readonly<AxisSpec & Record<string, unknown>>\n// >>;\n\nexport type AnnotationJson = MetadataJson<Annotation>;\n\nconst ValueTypeSchema = z.enum([\"Int\", \"Long\", \"Float\", \"Double\", \"String\"] as const);\nexport const AnnotationJson: AnnotationJson = {\n [Annotation.DiscreteValues]: z.array(z.string()).or(z.array(z.number())),\n [Annotation.Graph.Axis.HighCardinality]: z.boolean(),\n [Annotation.Graph.Axis.LowerLimit]: z.number(),\n [Annotation.Graph.Axis.UpperLimit]: z.number(),\n [Annotation.Graph.Axis.SymmetricRange]: z.boolean(),\n [Annotation.Graph.IsDenseAxis]: z.boolean(),\n [Annotation.Graph.Palette]: z.object({ mapping: z.record(z.number()), name: z.string() }),\n [Annotation.Graph.Thresholds]: z.array(\n z.object({\n columnId: z.object({ valueType: ValueTypeSchema, name: z.string() }),\n value: z.number(),\n }),\n ),\n [Annotation.Graph.TreatAbsentValuesAs]: z.number(),\n [Annotation.Graph.IsVirtual]: z.boolean(),\n [Annotation.HideDataFromUi]: z.boolean(),\n [Annotation.HideDataFromGraphs]: z.boolean(),\n [Annotation.IsDiscreteFilter]: z.boolean(),\n [Annotation.IsLinkerColumn]: z.boolean(),\n [Annotation.IsSubset]: z.boolean(),\n [Annotation.Max]: z.number(),\n [Annotation.Min]: z.number(),\n [Annotation.MultipliesBy]: z.array(z.string()),\n [Annotation.Parents]: z.array(z.string()),\n [Annotation.Sequence.Annotation.Mapping]: z.record(z.string(), z.string()),\n [Annotation.Sequence.IsAnnotation]: z.boolean(),\n [Annotation.Table.OrderPriority]: z.number(),\n [Annotation.Trace]: z.record(z.string(), z.unknown()),\n [Annotation.VDJ.IsAssemblingFeature]: z.boolean(),\n};\n\n/// Helper function for reading plain annotation values\nexport function readAnnotation<T extends keyof Annotation>(\n spec: { annotations?: Metadata | undefined } | undefined,\n key: T,\n): Annotation[T] | undefined {\n return readMetadata<Annotation, T>(spec?.annotations, key);\n}\n\n/// Helper function for reading json-encoded annotation values, throws on JSON parsing error\nexport function readAnnotationJsonOrThrow<T extends keyof AnnotationJson>(\n spec: { annotations?: Metadata | undefined } | undefined,\n key: T,\n): z.infer<AnnotationJson[T]> | undefined {\n return readMetadataJsonOrThrow<Annotation, T>(\n spec?.annotations,\n AnnotationJson,\n key,\n \"readAnnotationJsonOrThrow\",\n );\n}\n\n/// Helper function for reading json-encoded annotation values, returns undefined on JSON parsing error\nexport function readAnnotationJson<T extends keyof AnnotationJson>(\n spec: { annotations?: Metadata | undefined } | undefined,\n key: T,\n): z.infer<AnnotationJson[T]> | undefined {\n return readMetadataJson<Annotation, T>(spec?.annotations, AnnotationJson, key);\n}\n\nexport function isLinkerColumn(column: PColumnSpec): boolean {\n return !!readAnnotationJson(column, Annotation.IsLinkerColumn);\n}\n\n/**\n * Specification of an individual axis.\n *\n * Each axis is a part of a composite key that addresses data inside the PColumn.\n *\n * Each record inside a PColumn is addressed by a unique tuple of values set for\n * all the axes specified in the column spec.\n */\nexport type AxisSpec = {\n /** Type of the axis value. Should not use non-key types like float or double. */\n readonly type: AxisValueType;\n\n /** Name of the axis */\n readonly name: string;\n\n /** Adds auxiliary information to the axis name, type and parents to form a\n * unique identifier */\n readonly domain?: Record<string, string>;\n\n /** Context domain provides additional axis identity that is matched\n * by kinship rules (subset/superset/overlap) rather than exact equality */\n readonly contextDomain?: Record<string, string>;\n\n /** Any additional information attached to the axis that does not affect its\n * identifier */\n readonly annotations?: Record<string, string>;\n\n /**\n * Parent axes provide contextual grouping for the axis in question, establishing\n * a hierarchy where the current axis is dependent on one or more axes for its\n * full definition and meaning. For instance, in a data structure where each\n * \"container\" axis may contain multiple \"item\" axes, the `item` axis would\n * list the index of the `container` axis in this field to denote its dependency.\n *\n * This means that the identity or significance of the `item` axis is only\n * interpretable when combined with its parent `container` axis. An `item` axis\n * index by itself may be non-unique and only gains uniqueness within the context\n * of its parent `container`. Therefore, the `parentAxes` field is essential for\n * mapping these relationships and ensuring data coherence across nested or\n * multi-level data models.\n *\n * A list of zero-based indices of parent axes in the overall axes specification\n * from the column spec. Each index corresponds to the position of a parent axis\n * in the list that defines the structure of the data model.\n */\n readonly parentAxes?: number[];\n};\n\n/** Parents are specs, not indexes; normalized axis can be used considering its parents independently from column */\nexport interface AxisSpecNormalized extends Omit<AxisSpec, \"parentAxes\"> {\n parentAxesSpec: AxisSpecNormalized[];\n}\n\n/** Tree: axis is a root, its parents are children */\nexport type AxisTree = {\n axis: AxisSpecNormalized;\n children: AxisTree[]; // parents\n};\n\nfunction makeAxisTree(axis: AxisSpecNormalized): AxisTree {\n return { axis, children: [] };\n}\n\n/** Build tree by axis parents annotations */\nexport function getAxesTree(rootAxis: AxisSpecNormalized): AxisTree {\n const root = makeAxisTree(rootAxis);\n let nodesQ = [root];\n while (nodesQ.length) {\n const nextNodes: AxisTree[] = [];\n for (const node of nodesQ) {\n node.children = node.axis.parentAxesSpec.map(makeAxisTree);\n nextNodes.push(...node.children);\n }\n nodesQ = nextNodes;\n }\n return root;\n}\n\n/** Get set of canonicalized axisIds from axisTree */\nexport function getSetFromAxisTree(tree: AxisTree): Set<CanonicalizedJson<AxisId>> {\n const set = new Set([canonicalizeJson(getAxisId(tree.axis))]);\n let nodesQ = [tree];\n while (nodesQ.length) {\n const nextNodes = [];\n for (const node of nodesQ) {\n for (const parent of node.children) {\n set.add(canonicalizeJson(getAxisId(parent.axis)));\n nextNodes.push(parent);\n }\n }\n nodesQ = nextNodes;\n }\n return set;\n}\n\n/** Get array of axisSpecs from axisTree */\nexport function getArrayFromAxisTree(tree: AxisTree): AxisSpecNormalized[] {\n const res = [tree.axis];\n let nodesQ = [tree];\n while (nodesQ.length) {\n const nextNodes = [];\n for (const node of nodesQ) {\n for (const parent of node.children) {\n res.push(parent.axis);\n nextNodes.push(parent);\n }\n }\n nodesQ = nextNodes;\n }\n return res;\n}\n\nexport function canonicalizeAxisWithParents(axis: AxisSpecNormalized) {\n return canonicalizeJson(getArrayFromAxisTree(getAxesTree(axis)).map(getAxisId));\n}\n\nfunction normalizingAxesComparator(\n axis1: AxisSpecNormalized,\n axis2: AxisSpecNormalized,\n): 1 | -1 | 0 {\n if (axis1.name !== axis2.name) {\n return axis1.name < axis2.name ? 1 : -1;\n }\n if (axis1.type !== axis2.type) {\n return axis1.type < axis2.type ? 1 : -1;\n }\n const domain1 = canonicalizeJson(axis1.domain ?? {});\n const domain2 = canonicalizeJson(axis2.domain ?? {});\n if (domain1 !== domain2) {\n return domain1 < domain2 ? 1 : -1;\n }\n\n const contextDomain1 = canonicalizeJson(axis1.contextDomain ?? {});\n const contextDomain2 = canonicalizeJson(axis2.contextDomain ?? {});\n if (contextDomain1 !== contextDomain2) {\n return contextDomain1 < contextDomain2 ? 1 : -1;\n }\n\n const parents1 = canonicalizeAxisWithParents(axis1);\n const parents2 = canonicalizeAxisWithParents(axis2);\n\n if (parents1 !== parents2) {\n return parents1 < parents2 ? 1 : -1;\n }\n\n const annotation1 = canonicalizeJson(axis1.annotations ?? {});\n const annotation2 = canonicalizeJson(axis2.annotations ?? {});\n if (annotation1 !== annotation2) {\n return annotation1 < annotation2 ? 1 : -1;\n }\n return 0;\n}\n\nfunction parseParentsFromAnnotations(axis: AxisSpec) {\n const parentsList = readAnnotationJson(axis, Annotation.Parents);\n if (parentsList === undefined) {\n return [];\n }\n return parentsList;\n}\n\nfunction sortParentsDeep(axisSpec: AxisSpecNormalized) {\n axisSpec.parentAxesSpec.forEach(sortParentsDeep);\n axisSpec.parentAxesSpec.sort(normalizingAxesComparator);\n}\n\nfunction hasCycleOfParents(axisSpec: AxisSpecNormalized) {\n const root = makeAxisTree(axisSpec);\n let nodesQ = [root];\n const ancestors = new Set(canonicalizeJson(getAxisId(axisSpec)));\n while (nodesQ.length) {\n const nextNodes: AxisTree[] = [];\n const levelIds = new Set<CanonicalizedJson<AxisId>>();\n for (const node of nodesQ) {\n node.children = node.axis.parentAxesSpec.map(makeAxisTree);\n for (const child of node.children) {\n const childId = canonicalizeJson(getAxisId(child.axis));\n if (!levelIds.has(childId)) {\n nextNodes.push(child);\n levelIds.add(childId);\n if (ancestors.has(childId)) {\n return true;\n }\n ancestors.add(childId);\n }\n }\n }\n nodesQ = nextNodes;\n }\n return false;\n}\n\n/** Create list of normalized axisSpec (parents are in array of specs, not indexes) */\nexport function getNormalizedAxesList(axes: AxisSpec[]): AxisSpecNormalized[] {\n if (!axes.length) {\n return [];\n }\n const modifiedAxes: AxisSpecNormalized[] = axes.map((axis) => {\n const { parentAxes: _, ...copiedRest } = axis;\n return { ...copiedRest, annotations: { ...copiedRest.annotations }, parentAxesSpec: [] };\n });\n\n axes.forEach((axis, idx) => {\n const modifiedAxis = modifiedAxes[idx];\n if (axis.parentAxes) {\n // if we have parents by indexes then take from the list\n modifiedAxis.parentAxesSpec = axis.parentAxes.map((idx) => modifiedAxes[idx]);\n } else {\n // else try to parse from annotation name\n const parents = parseParentsFromAnnotations(axis).map((name) =>\n modifiedAxes.find((axis) => axis.name === name),\n );\n modifiedAxis.parentAxesSpec = parents.some((p) => p === undefined)\n ? []\n : (parents as AxisSpecNormalized[]);\n }\n });\n\n if (modifiedAxes.some(hasCycleOfParents)) {\n // Axes list is broken\n modifiedAxes.forEach((axis) => {\n axis.parentAxesSpec = [];\n });\n } else {\n modifiedAxes.forEach((axis) => {\n sortParentsDeep(axis);\n });\n }\n\n return modifiedAxes;\n}\n\n/** Create list of regular axisSpec from normalized (parents are indexes, inside of current axes list) */\nexport function getDenormalizedAxesList(axesSpec: AxisSpecNormalized[]): AxisSpec[] {\n const idsList = axesSpec.map((axisSpec) => canonicalizeJson(getAxisId(axisSpec)));\n return axesSpec.map((axisSpec) => {\n const parentsIds = axisSpec.parentAxesSpec.map((axisSpec) =>\n canonicalizeJson(getAxisId(axisSpec)),\n );\n const parentIdxs = parentsIds.map((id) => idsList.indexOf(id));\n const { parentAxesSpec: _, ...copiedRest } = axisSpec;\n if (parentIdxs.length) {\n return { ...copiedRest, parentAxes: parentIdxs } as AxisSpec;\n }\n return copiedRest;\n });\n}\n\n/**\n * Resolve annotation-based parents (`pl7.app/parents`) to numeric `parentAxes`\n * on a column spec. Returns the spec unchanged if all axes already use numeric\n * indices or have no parent annotations.\n */\nexport function resolveAnnotationParents(spec: PColumnSpec): PColumnSpec {\n const hasAnnotationParents = spec.axesSpec.some(\n (axis) => !!readAnnotationJson(axis, Annotation.Parents),\n );\n if (!hasAnnotationParents) return spec;\n\n const normalized = getNormalizedAxesList(spec.axesSpec);\n const denormalized = getDenormalizedAxesList(normalized);\n return { ...spec, axesSpec: denormalized };\n}\n\n/** Common type representing spec for all the axes in a column */\nexport type AxesSpec = AxisSpec[];\n\n/// Well-known column names\nexport const PColumnName = {\n Label: \"pl7.app/label\",\n Table: {\n RowSelection: \"pl7.app/table/row-selection\",\n },\n VDJ: {\n LeadSelection: \"pl7.app/vdj/lead-selection\",\n RankingOrder: \"pl7.app/vdj/ranking-order\",\n Sequence: \"pl7.app/vdj/sequence\",\n },\n} as const;\n\n/// Well-known axis names\nexport const PAxisName = {\n SampleId: \"pl7.app/sampleId\",\n VDJ: {\n Assay: {\n SequenceId: \"pl7.app/vdj/assay/sequenceId\",\n },\n ClusterId: \"pl7.app/vdj/clusterId\",\n ClonotypeKey: \"pl7.app/vdj/clonotypeKey\",\n ScClonotypeKey: \"pl7.app/vdj/scClonotypeKey\",\n },\n} as const;\n\nexport function isLabelColumn(column: PColumnSpec) {\n return column.axesSpec.length === 1 && column.name === PColumnName.Label;\n}\n\n/**\n * Full column specification including all axes specs and specs of the column\n * itself.\n *\n * A PColumn in its essence represents a mapping from a fixed size, explicitly\n * typed tuple to an explicitly typed value.\n *\n * (axis1Value1, axis2Value1, ...) -> columnValue\n *\n * Each element in tuple correspond to the axis having the same index in axesSpec.\n */\nexport type PUniversalColumnSpec = PObjectSpec & {\n /** Defines specific type of BObject, the most generic type of unit of\n * information in Platforma Project. */\n readonly kind: \"PColumn\";\n\n /** Type of column values */\n readonly valueType: string;\n\n /** Column name */\n readonly name: string;\n\n /** Adds auxiliary information to the axis name, type and parents to form a\n * unique identifier */\n readonly domain?: Record<string, string>;\n\n /** Context domain provides additional column identity that is matched\n * by kinship rules (subset/superset/overlap) rather than exact equality */\n readonly contextDomain?: Record<string, string>;\n\n /** Any additional information attached to the column that does not affect its\n * identifier */\n readonly annotations?: Record<string, string>;\n\n /** A list of zero-based indices of parent axes from the {@link axesSpec} array. */\n readonly parentAxes?: number[];\n\n /** Axes specifications */\n readonly axesSpec: AxesSpec;\n};\n\n/**\n * Specification of a data column.\n *\n * Data column is a specialized type of PColumn that stores only simple values (strings and numbers)\n * addressed by multiple keys. This is in contrast to other PColumn variants that can store more complex\n * values like files or other abstract data types. Data columns are optimized for storing and processing\n * basic tabular data.\n */\nexport type PDataColumnSpec = PUniversalColumnSpec & {\n /** Type of column values */\n readonly valueType: ValueType;\n};\n\n// @todo: change this to PUniversalColumnSpec\nexport type PColumnSpec = PDataColumnSpec;\n\n/** Unique PColumnSpec identifier */\nexport type PColumnSpecId = {\n /** Defines specific type of BObject, the most generic type of unit of\n * information in Platforma Project. */\n readonly kind: \"PColumn\";\n\n /** Type of column values */\n readonly valueType: ValueType;\n\n /** Column name */\n readonly name: string;\n\n /** Adds auxiliary information to the axis name, type and parents to form a\n * unique identifier */\n readonly domain?: Record<string, string>;\n\n /** Context domain provides additional column identity that is matched\n * by kinship rules (subset/superset/overlap) rather than exact equality */\n readonly contextDomain?: Record<string, string>;\n\n /** A list of zero-based indices of parent axes from the {@link axesSpec} array. */\n readonly parentAxes?: number[];\n\n /** Axes id */\n readonly axesId: AxesId;\n};\n\nexport function getPColumnSpecId(spec: PColumnSpec): PColumnSpecId {\n return {\n kind: spec.kind,\n valueType: spec.valueType,\n name: spec.name,\n domain: spec.domain,\n contextDomain: spec.contextDomain,\n parentAxes: spec.parentAxes,\n axesId: getAxesId(spec.axesSpec),\n };\n}\n\nexport interface PColumn<Data> extends PObject<Data> {\n /** PColumn spec, allowing it to be found among other PObjects */\n readonly spec: PColumnSpec;\n}\n\nexport type PColumnLazy<T> = PColumn<() => T>;\n\n/** Columns in a PFrame also have internal identifier, this object represents\n * combination of specs and such id */\nexport interface PColumnIdAndSpec {\n /** Internal column id within the PFrame */\n readonly columnId: PObjectId;\n\n /** Column spec */\n readonly spec: PColumnSpec;\n}\n\n/** Get column id and spec from a column */\nexport function getColumnIdAndSpec<Data>(column: PColumn<Data>): PColumnIdAndSpec {\n return {\n columnId: column.id,\n spec: column.spec,\n };\n}\n\n/** Information returned by {@link PFrame.listColumns} method */\nexport interface PColumnInfo extends PColumnIdAndSpec {\n /** True if data was associated with this PColumn */\n readonly hasData: boolean;\n}\n\nexport interface AxisId {\n /** Type of the axis or column value. For an axis should not use non-key\n * types like float or double. */\n readonly type: AxisValueType;\n\n /** Name of the axis or column */\n readonly name: string;\n\n /** Adds auxiliary information to the axis or column name and type to form a\n * unique identifier */\n readonly domain?: Record<string, string>;\n\n /** Context domain provides additional axis identity that is matched\n * by kinship rules (subset/superset/overlap) rather than exact equality */\n readonly contextDomain?: Record<string, string>;\n}\n\n/** Array of axis ids */\nexport type AxesId = AxisId[];\n\n/** Extracts axis ids from axis spec */\nexport function getAxisId(spec: AxisSpec): AxisId {\n const { type, name, domain, contextDomain } = spec;\n const result: AxisId = { type, name };\n if (domain && Object.entries(domain).length > 0) {\n Object.assign(result, { domain });\n }\n if (contextDomain && Object.entries(contextDomain).length > 0) {\n Object.assign(result, { contextDomain });\n }\n return result;\n}\n\n/** Extracts axes ids from axes spec array from column spec */\nexport function getAxesId(spec: AxesSpec): AxesId {\n return spec.map(getAxisId);\n}\n\n/** Canonicalizes axis id */\nexport function canonicalizeAxisId(id: AxisId): CanonicalizedJson<AxisId> {\n return canonicalizeJson(getAxisId(id));\n}\n\n/** Returns true if all domains from query are found in target */\nfunction matchDomain(query?: Record<string, string>, target?: Record<string, string>) {\n if (query === undefined) return target === undefined;\n if (target === undefined) return true;\n for (const k in target) {\n if (query[k] !== target[k]) return false;\n }\n return true;\n}\n\n/** Returns whether \"match\" axis id is compatible with the \"query\" */\nexport function matchAxisId(query: AxisId, target: AxisId): boolean {\n return (\n query.name === target.name &&\n matchDomain(query.domain, target.domain) &&\n matchDomain(query.contextDomain, target.contextDomain)\n );\n}\n\nexport function getTypeFromPColumnOrAxisSpec(spec: PColumnSpec | AxisSpec): ValueType {\n return \"valueType\" in spec ? spec.valueType : spec.type;\n}\n\nexport function isAxisId(id: unknown): id is AxisId {\n return typeof id === \"object\" && id !== null && \"name\" in id && \"type\" in id;\n}\n"],"mappings":";;;;;AAKA,MAAa,YAAY;CACvB,KAAK;CACL,MAAM;CACN,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,OAAO;CACR;AAUD,SAAgB,aACd,UACA,KACkB;AAClB,QAAQ,WAA6B;;AAUvC,SAAgB,wBACd,UACA,cACA,KACA,oBAA4B,2BACa;CACzC,MAAM,OAAO,aAAmB,UAAU,IAAI;AAC9C,KAAI,SAAS,KAAA,EAAW,QAAO,KAAA;CAE/B,MAAM,SAAS,aAAa;AAC5B,KAAI;EACF,MAAM,QAAQ,KAAK,MAAM,KAAK;AAC9B,SAAO,OAAO,MAAM,MAAM;UACnB,OAAgB;AACvB,QAAM,IAAI,MACR,GAAG,kBAAkB,gBACX,OAAO,IAAI,CAAC,WACV,KAAK,WACLA,eAAAA,YAAY,MAAM,GAC/B;;;AAIL,SAAgB,iBACd,UACA,cACA,KACyC;AACzC,KAAI;AACF,SAAO,wBAAwB,UAAU,cAAc,IAAI;SACrD;AACN;;;AAKJ,MAAa,SAAS;CACpB,UAAU;CACV,SAAS;CACT,KAAK;EACH,YAAY,EACV,SAAS,kCACV;EACD,kBAAkB,EAChB,OAAO,sCACR;EACF;CACF;AAUD,MAAa,aAAyB,EAAE;AAGxC,SAAgB,WACd,MACA,KACuB;AACvB,QAAO,aAAwB,MAAM,QAAQ,IAAI;;AAInD,SAAgB,sBACd,MACA,KACoC;AACpC,QAAO,wBAAmC,MAAM,QAAQ,YAAY,KAAK,wBAAwB;;AAInG,SAAgB,eACd,MACA,KACoC;AACpC,QAAO,iBAA4B,MAAM,QAAQ,YAAY,IAAI;;AAInE,MAAa,aAAa;CACxB,YAAY;CACZ,UAAU;CACV,aAAa;CACb,gBAAgB;CAChB,QAAQ;CACR,OAAO;EACL,MAAM;GACJ,iBAAiB;GACjB,YAAY;GACZ,gBAAgB;GAChB,YAAY;GACb;EACD,aAAa;EACb,WAAW;EACX,SAAS;EACT,YAAY;EACZ,qBAAqB;EACtB;CACD,gBAAgB;CAChB,oBAAoB;CACpB,kBAAkB;CAClB,UAAU;CACV,gBAAgB;CAChB,SAAS;CACT,UAAU;CACV,OAAO;CACP,KAAK;CACL,KAAK;CACL,cAAc;CACd,SAAS;CACT,OAAO;EACL,eAAe;EACf,cAAc;EACf;CACD,UAAU;EACR,YAAY,EACV,SAAS,uCACV;EACD,cAAc;EACf;CACD,OAAO;EACL,YAAY;EACZ,eAAe;EACf,YAAY;EACb;CACD,OAAO;CACP,KAAK;EACH,qBAAqB;EACrB,gBAAgB;EACjB;CACF;AA0DD,MAAM,kBAAkBC,IAAAA,EAAE,KAAK;CAAC;CAAO;CAAQ;CAAS;CAAU;CAAS,CAAU;AACrF,MAAa,iBAAiC;EAC3C,WAAW,iBAAiBA,IAAAA,EAAE,MAAMA,IAAAA,EAAE,QAAQ,CAAC,CAAC,GAAGA,IAAAA,EAAE,MAAMA,IAAAA,EAAE,QAAQ,CAAC,CAAC;EACvE,WAAW,MAAM,KAAK,kBAAkBA,IAAAA,EAAE,SAAS;EACnD,WAAW,MAAM,KAAK,aAAaA,IAAAA,EAAE,QAAQ;EAC7C,WAAW,MAAM,KAAK,aAAaA,IAAAA,EAAE,QAAQ;EAC7C,WAAW,MAAM,KAAK,iBAAiBA,IAAAA,EAAE,SAAS;EAClD,WAAW,MAAM,cAAcA,IAAAA,EAAE,SAAS;EAC1C,WAAW,MAAM,UAAUA,IAAAA,EAAE,OAAO;EAAE,SAASA,IAAAA,EAAE,OAAOA,IAAAA,EAAE,QAAQ,CAAC;EAAE,MAAMA,IAAAA,EAAE,QAAQ;EAAE,CAAC;EACxF,WAAW,MAAM,aAAaA,IAAAA,EAAE,MAC/BA,IAAAA,EAAE,OAAO;EACP,UAAUA,IAAAA,EAAE,OAAO;GAAE,WAAW;GAAiB,MAAMA,IAAAA,EAAE,QAAQ;GAAE,CAAC;EACpE,OAAOA,IAAAA,EAAE,QAAQ;EAClB,CAAC,CACH;EACA,WAAW,MAAM,sBAAsBA,IAAAA,EAAE,QAAQ;EACjD,WAAW,MAAM,YAAYA,IAAAA,EAAE,SAAS;EACxC,WAAW,iBAAiBA,IAAAA,EAAE,SAAS;EACvC,WAAW,qBAAqBA,IAAAA,EAAE,SAAS;EAC3C,WAAW,mBAAmBA,IAAAA,EAAE,SAAS;EACzC,WAAW,iBAAiBA,IAAAA,EAAE,SAAS;EACvC,WAAW,WAAWA,IAAAA,EAAE,SAAS;EACjC,WAAW,MAAMA,IAAAA,EAAE,QAAQ;EAC3B,WAAW,MAAMA,IAAAA,EAAE,QAAQ;EAC3B,WAAW,eAAeA,IAAAA,EAAE,MAAMA,IAAAA,EAAE,QAAQ,CAAC;EAC7C,WAAW,UAAUA,IAAAA,EAAE,MAAMA,IAAAA,EAAE,QAAQ,CAAC;EACxC,WAAW,SAAS,WAAW,UAAUA,IAAAA,EAAE,OAAOA,IAAAA,EAAE,QAAQ,EAAEA,IAAAA,EAAE,QAAQ,CAAC;EACzE,WAAW,SAAS,eAAeA,IAAAA,EAAE,SAAS;EAC9C,WAAW,MAAM,gBAAgBA,IAAAA,EAAE,QAAQ;EAC3C,WAAW,QAAQA,IAAAA,EAAE,OAAOA,IAAAA,EAAE,QAAQ,EAAEA,IAAAA,EAAE,SAAS,CAAC;EACpD,WAAW,IAAI,sBAAsBA,IAAAA,EAAE,SAAS;CAClD;AAGD,SAAgB,eACd,MACA,KAC2B;AAC3B,QAAO,aAA4B,MAAM,aAAa,IAAI;;AAI5D,SAAgB,0BACd,MACA,KACwC;AACxC,QAAO,wBACL,MAAM,aACN,gBACA,KACA,4BACD;;AAIH,SAAgB,mBACd,MACA,KACwC;AACxC,QAAO,iBAAgC,MAAM,aAAa,gBAAgB,IAAI;;AAGhF,SAAgB,eAAe,QAA8B;AAC3D,QAAO,CAAC,CAAC,mBAAmB,QAAQ,WAAW,eAAe;;AA8DhE,SAAS,aAAa,MAAoC;AACxD,QAAO;EAAE;EAAM,UAAU,EAAE;EAAE;;;AAI/B,SAAgB,YAAY,UAAwC;CAClE,MAAM,OAAO,aAAa,SAAS;CACnC,IAAI,SAAS,CAAC,KAAK;AACnB,QAAO,OAAO,QAAQ;EACpB,MAAM,YAAwB,EAAE;AAChC,OAAK,MAAM,QAAQ,QAAQ;AACzB,QAAK,WAAW,KAAK,KAAK,eAAe,IAAI,aAAa;AAC1D,aAAU,KAAK,GAAG,KAAK,SAAS;;AAElC,WAAS;;AAEX,QAAO;;;AAIT,SAAgB,mBAAmB,MAAgD;CACjF,MAAM,MAAM,IAAI,IAAI,CAACC,aAAAA,iBAAiB,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC;CAC7D,IAAI,SAAS,CAAC,KAAK;AACnB,QAAO,OAAO,QAAQ;EACpB,MAAM,YAAY,EAAE;AACpB,OAAK,MAAM,QAAQ,OACjB,MAAK,MAAM,UAAU,KAAK,UAAU;AAClC,OAAI,IAAIA,aAAAA,iBAAiB,UAAU,OAAO,KAAK,CAAC,CAAC;AACjD,aAAU,KAAK,OAAO;;AAG1B,WAAS;;AAEX,QAAO;;;AAIT,SAAgB,qBAAqB,MAAsC;CACzE,MAAM,MAAM,CAAC,KAAK,KAAK;CACvB,IAAI,SAAS,CAAC,KAAK;AACnB,QAAO,OAAO,QAAQ;EACpB,MAAM,YAAY,EAAE;AACpB,OAAK,MAAM,QAAQ,OACjB,MAAK,MAAM,UAAU,KAAK,UAAU;AAClC,OAAI,KAAK,OAAO,KAAK;AACrB,aAAU,KAAK,OAAO;;AAG1B,WAAS;;AAEX,QAAO;;AAGT,SAAgB,4BAA4B,MAA0B;AACpE,QAAOA,aAAAA,iBAAiB,qBAAqB,YAAY,KAAK,CAAC,CAAC,IAAI,UAAU,CAAC;;AAGjF,SAAS,0BACP,OACA,OACY;AACZ,KAAI,MAAM,SAAS,MAAM,KACvB,QAAO,MAAM,OAAO,MAAM,OAAO,IAAI;AAEvC,KAAI,MAAM,SAAS,MAAM,KACvB,QAAO,MAAM,OAAO,MAAM,OAAO,IAAI;CAEvC,MAAM,UAAUA,aAAAA,iBAAiB,MAAM,UAAU,EAAE,CAAC;CACpD,MAAM,UAAUA,aAAAA,iBAAiB,MAAM,UAAU,EAAE,CAAC;AACpD,KAAI,YAAY,QACd,QAAO,UAAU,UAAU,IAAI;CAGjC,MAAM,iBAAiBA,aAAAA,iBAAiB,MAAM,iBAAiB,EAAE,CAAC;CAClE,MAAM,iBAAiBA,aAAAA,iBAAiB,MAAM,iBAAiB,EAAE,CAAC;AAClE,KAAI,mBAAmB,eACrB,QAAO,iBAAiB,iBAAiB,IAAI;CAG/C,MAAM,WAAW,4BAA4B,MAAM;CACnD,MAAM,WAAW,4BAA4B,MAAM;AAEnD,KAAI,aAAa,SACf,QAAO,WAAW,WAAW,IAAI;CAGnC,MAAM,cAAcA,aAAAA,iBAAiB,MAAM,eAAe,EAAE,CAAC;CAC7D,MAAM,cAAcA,aAAAA,iBAAiB,MAAM,eAAe,EAAE,CAAC;AAC7D,KAAI,gBAAgB,YAClB,QAAO,cAAc,cAAc,IAAI;AAEzC,QAAO;;AAGT,SAAS,4BAA4B,MAAgB;CACnD,MAAM,cAAc,mBAAmB,MAAM,WAAW,QAAQ;AAChE,KAAI,gBAAgB,KAAA,EAClB,QAAO,EAAE;AAEX,QAAO;;AAGT,SAAS,gBAAgB,UAA8B;AACrD,UAAS,eAAe,QAAQ,gBAAgB;AAChD,UAAS,eAAe,KAAK,0BAA0B;;AAGzD,SAAS,kBAAkB,UAA8B;CAEvD,IAAI,SAAS,CADA,aAAa,SAAS,CAChB;CACnB,MAAM,YAAY,IAAI,IAAIA,aAAAA,iBAAiB,UAAU,SAAS,CAAC,CAAC;AAChE,QAAO,OAAO,QAAQ;EACpB,MAAM,YAAwB,EAAE;EAChC,MAAM,2BAAW,IAAI,KAAgC;AACrD,OAAK,MAAM,QAAQ,QAAQ;AACzB,QAAK,WAAW,KAAK,KAAK,eAAe,IAAI,aAAa;AAC1D,QAAK,MAAM,SAAS,KAAK,UAAU;IACjC,MAAM,UAAUA,aAAAA,iBAAiB,UAAU,MAAM,KAAK,CAAC;AACvD,QAAI,CAAC,SAAS,IAAI,QAAQ,EAAE;AAC1B,eAAU,KAAK,MAAM;AACrB,cAAS,IAAI,QAAQ;AACrB,SAAI,UAAU,IAAI,QAAQ,CACxB,QAAO;AAET,eAAU,IAAI,QAAQ;;;;AAI5B,WAAS;;AAEX,QAAO;;;AAIT,SAAgB,sBAAsB,MAAwC;AAC5E,KAAI,CAAC,KAAK,OACR,QAAO,EAAE;CAEX,MAAM,eAAqC,KAAK,KAAK,SAAS;EAC5D,MAAM,EAAE,YAAY,GAAG,GAAG,eAAe;AACzC,SAAO;GAAE,GAAG;GAAY,aAAa,EAAE,GAAG,WAAW,aAAa;GAAE,gBAAgB,EAAE;GAAE;GACxF;AAEF,MAAK,SAAS,MAAM,QAAQ;EAC1B,MAAM,eAAe,aAAa;AAClC,MAAI,KAAK,WAEP,cAAa,iBAAiB,KAAK,WAAW,KAAK,QAAQ,aAAa,KAAK;OACxE;GAEL,MAAM,UAAU,4BAA4B,KAAK,CAAC,KAAK,SACrD,aAAa,MAAM,SAAS,KAAK,SAAS,KAAK,CAChD;AACD,gBAAa,iBAAiB,QAAQ,MAAM,MAAM,MAAM,KAAA,EAAU,GAC9D,EAAE,GACD;;GAEP;AAEF,KAAI,aAAa,KAAK,kBAAkB,CAEtC,cAAa,SAAS,SAAS;AAC7B,OAAK,iBAAiB,EAAE;GACxB;KAEF,cAAa,SAAS,SAAS;AAC7B,kBAAgB,KAAK;GACrB;AAGJ,QAAO;;;AAIT,SAAgB,wBAAwB,UAA4C;CAClF,MAAM,UAAU,SAAS,KAAK,aAAaA,aAAAA,iBAAiB,UAAU,SAAS,CAAC,CAAC;AACjF,QAAO,SAAS,KAAK,aAAa;EAIhC,MAAM,aAHa,SAAS,eAAe,KAAK,aAC9CA,aAAAA,iBAAiB,UAAU,SAAS,CAAC,CACtC,CAC6B,KAAK,OAAO,QAAQ,QAAQ,GAAG,CAAC;EAC9D,MAAM,EAAE,gBAAgB,GAAG,GAAG,eAAe;AAC7C,MAAI,WAAW,OACb,QAAO;GAAE,GAAG;GAAY,YAAY;GAAY;AAElD,SAAO;GACP;;;;;;;AAQJ,SAAgB,yBAAyB,MAAgC;AAIvE,KAAI,CAHyB,KAAK,SAAS,MACxC,SAAS,CAAC,CAAC,mBAAmB,MAAM,WAAW,QAAQ,CACzD,CAC0B,QAAO;CAGlC,MAAM,eAAe,wBADF,sBAAsB,KAAK,SAAS,CACC;AACxD,QAAO;EAAE,GAAG;EAAM,UAAU;EAAc;;AAO5C,MAAa,cAAc;CACzB,OAAO;CACP,OAAO,EACL,cAAc,+BACf;CACD,KAAK;EACH,eAAe;EACf,cAAc;EACd,UAAU;EACX;CACF;AAGD,MAAa,YAAY;CACvB,UAAU;CACV,KAAK;EACH,OAAO,EACL,YAAY,gCACb;EACD,WAAW;EACX,cAAc;EACd,gBAAgB;EACjB;CACF;AAED,SAAgB,cAAc,QAAqB;AACjD,QAAO,OAAO,SAAS,WAAW,KAAK,OAAO,SAAS,YAAY;;AAuFrE,SAAgB,iBAAiB,MAAkC;AACjE,QAAO;EACL,MAAM,KAAK;EACX,WAAW,KAAK;EAChB,MAAM,KAAK;EACX,QAAQ,KAAK;EACb,eAAe,KAAK;EACpB,YAAY,KAAK;EACjB,QAAQ,UAAU,KAAK,SAAS;EACjC;;;AAqBH,SAAgB,mBAAyB,QAAyC;AAChF,QAAO;EACL,UAAU,OAAO;EACjB,MAAM,OAAO;EACd;;;AA8BH,SAAgB,UAAU,MAAwB;CAChD,MAAM,EAAE,MAAM,MAAM,QAAQ,kBAAkB;CAC9C,MAAM,SAAiB;EAAE;EAAM;EAAM;AACrC,KAAI,UAAU,OAAO,QAAQ,OAAO,CAAC,SAAS,EAC5C,QAAO,OAAO,QAAQ,EAAE,QAAQ,CAAC;AAEnC,KAAI,iBAAiB,OAAO,QAAQ,cAAc,CAAC,SAAS,EAC1D,QAAO,OAAO,QAAQ,EAAE,eAAe,CAAC;AAE1C,QAAO;;;AAIT,SAAgB,UAAU,MAAwB;AAChD,QAAO,KAAK,IAAI,UAAU;;;AAI5B,SAAgB,mBAAmB,IAAuC;AACxE,QAAOA,aAAAA,iBAAiB,UAAU,GAAG,CAAC;;;AAIxC,SAAS,YAAY,OAAgC,QAAiC;AACpF,KAAI,UAAU,KAAA,EAAW,QAAO,WAAW,KAAA;AAC3C,KAAI,WAAW,KAAA,EAAW,QAAO;AACjC,MAAK,MAAM,KAAK,OACd,KAAI,MAAM,OAAO,OAAO,GAAI,QAAO;AAErC,QAAO;;;AAIT,SAAgB,YAAY,OAAe,QAAyB;AAClE,QACE,MAAM,SAAS,OAAO,QACtB,YAAY,MAAM,QAAQ,OAAO,OAAO,IACxC,YAAY,MAAM,eAAe,OAAO,cAAc;;AAI1D,SAAgB,6BAA6B,MAAyC;AACpF,QAAO,eAAe,OAAO,KAAK,YAAY,KAAK;;AAGrD,SAAgB,SAAS,IAA2B;AAClD,QAAO,OAAO,OAAO,YAAY,OAAO,QAAQ,UAAU,MAAM,UAAU"}
1
+ {"version":3,"file":"spec.cjs","names":["ensureError","z","canonicalizeJson"],"sources":["../../../../src/drivers/pframe/spec/spec.ts"],"sourcesContent":["import { ensureError } from \"../../../errors\";\nimport { canonicalizeJson, type CanonicalizedJson, type StringifiedJson } from \"../../../json\";\nimport type { PObject, PObjectId, PObjectSpec } from \"../../../pool\";\nimport { z } from \"zod\";\n\nexport const ValueType = {\n Int: \"Int\",\n Long: \"Long\",\n Float: \"Float\",\n Double: \"Double\",\n String: \"String\",\n Bytes: \"Bytes\",\n} as const;\n\nexport type AxisValueType = Extract<ValueType, \"Int\" | \"Long\" | \"String\">;\nexport type ColumnValueType = ValueType;\n\n/** PFrame columns and axes within them may store one of these types. */\nexport type ValueType = (typeof ValueType)[keyof typeof ValueType];\n\nexport type Metadata = Record<string, string>;\n\nexport function readMetadata<U extends Metadata, T extends keyof U = keyof U>(\n metadata: Metadata | undefined,\n key: T,\n): U[T] | undefined {\n return (metadata as U | undefined)?.[key];\n}\n\ntype MetadataJsonImpl<M> = {\n [P in keyof M as M[P] extends StringifiedJson ? P : never]: M[P] extends StringifiedJson<infer U>\n ? z.ZodType<U>\n : never;\n};\nexport type MetadataJson<M> = MetadataJsonImpl<Required<M>>;\n\nexport function readMetadataJsonOrThrow<M extends Metadata, T extends keyof MetadataJson<M>>(\n metadata: Metadata | undefined,\n metadataJson: MetadataJson<M>,\n key: T,\n methodNameInError: string = \"readMetadataJsonOrThrow\",\n): z.infer<MetadataJson<M>[T]> | undefined {\n const json = readMetadata<M, T>(metadata, key);\n if (json === undefined) return undefined;\n\n const schema = metadataJson[key];\n try {\n const value = JSON.parse(json);\n return schema.parse(value);\n } catch (error: unknown) {\n throw new Error(\n `${methodNameInError} failed, ` +\n `key: ${String(key)}, ` +\n `value: ${json}, ` +\n `error: ${ensureError(error)}`,\n );\n }\n}\n\nexport function readMetadataJson<M extends Metadata, T extends keyof MetadataJson<M>>(\n metadata: Metadata | undefined,\n metadataJson: MetadataJson<M>,\n key: T,\n): z.infer<MetadataJson<M>[T]> | undefined {\n try {\n return readMetadataJsonOrThrow(metadata, metadataJson, key);\n } catch {\n return undefined; // treat invalid values as unset\n }\n}\n\n/// Well-known domains\nexport const Domain = {\n Alphabet: \"pl7.app/alphabet\",\n BlockId: \"pl7.app/blockId\",\n VDJ: {\n Clustering: {\n BlockId: \"pl7.app/vdj/clustering/blockId\",\n },\n ScClonotypeChain: {\n Index: \"pl7.app/vdj/scClonotypeChain/index\",\n },\n },\n} as const;\n\nexport type Domain = Metadata &\n Partial<{\n [Domain.Alphabet]: \"nucleotide\" | \"aminoacid\" | (string & {});\n [Domain.BlockId]: string;\n [Domain.VDJ.ScClonotypeChain.Index]: \"primary\" | \"secondary\" | (string & {});\n }>;\n\nexport type DomainJson = MetadataJson<Domain>;\nexport const DomainJson: DomainJson = {};\n\n/// Helper function for reading plain domain values\nexport function readDomain<T extends keyof Domain>(\n spec: { domain?: Metadata | undefined } | undefined,\n key: T,\n): Domain[T] | undefined {\n return readMetadata<Domain, T>(spec?.domain, key);\n}\n\n/// Helper function for reading json-encoded domain values, throws on JSON parsing error\nexport function readDomainJsonOrThrow<T extends keyof DomainJson>(\n spec: { domain?: Metadata | undefined } | undefined,\n key: T,\n): z.infer<DomainJson[T]> | undefined {\n return readMetadataJsonOrThrow<Domain, T>(spec?.domain, DomainJson, key, \"readDomainJsonOrThrow\");\n}\n\n/// Helper function for reading json-encoded domain values, returns undefined on JSON parsing error\nexport function readDomainJson<T extends keyof DomainJson>(\n spec: { domain?: Metadata | undefined } | undefined,\n key: T,\n): z.infer<DomainJson[T]> | undefined {\n return readMetadataJson<Domain, T>(spec?.domain, DomainJson, key);\n}\n\n/// Well-known annotations\nexport const Annotation = {\n AxisNature: \"pl7.app/axisNature\",\n Alphabet: \"pl7.app/alphabet\",\n Description: \"pl7.app/description\",\n DiscreteValues: \"pl7.app/discreteValues\",\n Format: \"pl7.app/format\",\n Graph: {\n Axis: {\n HighCardinality: \"pl7.app/graph/axis/highCardinality\",\n LowerLimit: \"pl7.app/graph/axis/lowerLimit\",\n SymmetricRange: \"pl7.app/graph/axis/symmetricRange\",\n UpperLimit: \"pl7.app/graph/axis/upperLimit\",\n },\n IsDenseAxis: \"pl7.app/graph/isDenseAxis\",\n IsVirtual: \"pl7.app/graph/isVirtual\",\n Palette: \"pl7.app/graph/palette\",\n Thresholds: \"pl7.app/graph/thresholds\",\n TreatAbsentValuesAs: \"pl7.app/graph/treatAbsentValuesAs\",\n },\n HideDataFromUi: \"pl7.app/hideDataFromUi\",\n HideDataFromGraphs: \"pl7.app/hideDataFromGraphs\",\n IsDiscreteFilter: \"pl7.app/isDiscreteFilter\",\n IsAnchor: \"pl7.app/isAnchor\",\n IsLinkerColumn: \"pl7.app/isLinkerColumn\",\n IsScore: \"pl7.app/isScore\",\n IsSubset: \"pl7.app/isSubset\",\n Label: \"pl7.app/label\",\n LinkLabel: \"pl7.app/linkLabel\",\n Max: \"pl7.app/max\",\n Min: \"pl7.app/min\",\n MultipliesBy: \"pl7.app/multipliesBy\",\n Parents: \"pl7.app/parents\",\n Score: {\n DefaultCutoff: \"pl7.app/score/defaultCutoff\",\n RankingOrder: \"pl7.app/score/rankingOrder\",\n },\n Sequence: {\n Annotation: {\n Mapping: \"pl7.app/sequence/annotation/mapping\",\n },\n IsAnnotation: \"pl7.app/sequence/isAnnotation\",\n },\n Table: {\n FontFamily: \"pl7.app/table/fontFamily\",\n OrderPriority: \"pl7.app/table/orderPriority\",\n Visibility: \"pl7.app/table/visibility\",\n },\n Trace: \"pl7.app/trace\",\n VDJ: {\n IsAssemblingFeature: \"pl7.app/vdj/isAssemblingFeature\",\n IsMainSequence: \"pl7.app/vdj/isMainSequence\",\n },\n} as const;\n\nexport type Annotation = Metadata &\n Partial<{\n [Annotation.Alphabet]: \"nucleotide\" | \"aminoacid\" | (string & {});\n [Annotation.AxisNature]: \"homogeneous\" | \"heterogeneous\" | \"scaleCompatible\" | (string & {});\n [Annotation.Description]: string;\n [Annotation.DiscreteValues]: StringifiedJson<number[]> | StringifiedJson<string[]>;\n [Annotation.Format]: string;\n [Annotation.Graph.Axis.HighCardinality]: StringifiedJson<boolean>;\n [Annotation.Graph.Axis.LowerLimit]: StringifiedJson<number>;\n [Annotation.Graph.Axis.SymmetricRange]: StringifiedJson<boolean>;\n [Annotation.Graph.Axis.UpperLimit]: StringifiedJson<number>;\n [Annotation.Graph.IsDenseAxis]: StringifiedJson<boolean>;\n [Annotation.Graph.IsVirtual]: StringifiedJson<boolean>;\n [Annotation.Graph.Palette]: StringifiedJson<{ mapping: Record<string, number>; name: string }>;\n [Annotation.Graph.Thresholds]: StringifiedJson<\n { columnId: { valueType: ValueType; name: string }; value: number }[]\n >;\n [Annotation.Graph.TreatAbsentValuesAs]: StringifiedJson<number>;\n [Annotation.HideDataFromGraphs]: StringifiedJson<boolean>;\n [Annotation.HideDataFromUi]: StringifiedJson<boolean>;\n [Annotation.IsDiscreteFilter]: StringifiedJson<boolean>;\n [Annotation.IsLinkerColumn]: StringifiedJson<boolean>;\n [Annotation.IsSubset]: StringifiedJson<boolean>;\n [Annotation.Label]: string;\n [Annotation.Max]: StringifiedJson<number>;\n [Annotation.Min]: StringifiedJson<number>;\n [Annotation.MultipliesBy]: StringifiedJson<AxisSpec[\"name\"][]>;\n [Annotation.Parents]: StringifiedJson<AxisSpec[\"name\"][]>;\n [Annotation.Sequence.Annotation.Mapping]: StringifiedJson<Record<string, string>>;\n [Annotation.Sequence.IsAnnotation]: StringifiedJson<boolean>;\n [Annotation.Table.FontFamily]: string;\n [Annotation.Table.OrderPriority]: StringifiedJson<number>;\n [Annotation.Table.Visibility]: \"hidden\" | \"optional\" | (string & {});\n [Annotation.Trace]: StringifiedJson<Trace>;\n [Annotation.VDJ.IsAssemblingFeature]: StringifiedJson<boolean>;\n }>;\n\n/// One step in a column's derivation lineage. Only `type` and `label` are part\n/// of the typed public surface; writers may add fields (e.g. `id`, `importance`)\n/// passed through opaquely as `unknown`, accessed via explicit narrowing.\nconst TraceEntrySchema = z\n .object({\n type: z.string(),\n label: z.string(),\n })\n .catchall(z.unknown());\n\nexport type TraceEntry = z.infer<typeof TraceEntrySchema>;\n\nexport type Trace = TraceEntry[];\n\n// export const AxisSpec = z.object({\n// type: z.nativeEnum(ValueType),\n// name: z.string(),\n// domain: z.record(z.string(), z.string()).optional(),\n// annotations: z.record(z.string(), z.string()).optional(),\n// parentAxes: z.array(z.number()).optional(),\n// }).passthrough();\n//\n// type Expect<T extends true> = T;\n// type Equal<X, Y> =\n// (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false;\n//\n// type _test = Expect<Equal<\n// Readonly<z.infer<typeof AxisSpec>>,\n// Readonly<AxisSpec & Record<string, unknown>>\n// >>;\n\nexport type AnnotationJson = MetadataJson<Annotation>;\n\nconst ValueTypeSchema = z.enum([\"Int\", \"Long\", \"Float\", \"Double\", \"String\"] as const);\nexport const AnnotationJson: AnnotationJson = {\n [Annotation.DiscreteValues]: z.array(z.string()).or(z.array(z.number())),\n [Annotation.Graph.Axis.HighCardinality]: z.boolean(),\n [Annotation.Graph.Axis.LowerLimit]: z.number(),\n [Annotation.Graph.Axis.UpperLimit]: z.number(),\n [Annotation.Graph.Axis.SymmetricRange]: z.boolean(),\n [Annotation.Graph.IsDenseAxis]: z.boolean(),\n [Annotation.Graph.Palette]: z.object({ mapping: z.record(z.number()), name: z.string() }),\n [Annotation.Graph.Thresholds]: z.array(\n z.object({\n columnId: z.object({ valueType: ValueTypeSchema, name: z.string() }),\n value: z.number(),\n }),\n ),\n [Annotation.Graph.TreatAbsentValuesAs]: z.number(),\n [Annotation.Graph.IsVirtual]: z.boolean(),\n [Annotation.HideDataFromUi]: z.boolean(),\n [Annotation.HideDataFromGraphs]: z.boolean(),\n [Annotation.IsDiscreteFilter]: z.boolean(),\n [Annotation.IsLinkerColumn]: z.boolean(),\n [Annotation.IsSubset]: z.boolean(),\n [Annotation.Max]: z.number(),\n [Annotation.Min]: z.number(),\n [Annotation.MultipliesBy]: z.array(z.string()),\n [Annotation.Parents]: z.array(z.string()),\n [Annotation.Sequence.Annotation.Mapping]: z.record(z.string(), z.string()),\n [Annotation.Sequence.IsAnnotation]: z.boolean(),\n [Annotation.Table.OrderPriority]: z.number(),\n [Annotation.Trace]: z.array(TraceEntrySchema),\n [Annotation.VDJ.IsAssemblingFeature]: z.boolean(),\n};\n\n/// Helper function for reading plain annotation values\nexport function readAnnotation<T extends keyof Annotation>(\n spec: { annotations?: Metadata | undefined } | undefined,\n key: T,\n): Annotation[T] | undefined {\n return readMetadata<Annotation, T>(spec?.annotations, key);\n}\n\n/// Helper function for reading json-encoded annotation values, throws on JSON parsing error\nexport function readAnnotationJsonOrThrow<T extends keyof AnnotationJson>(\n spec: { annotations?: Metadata | undefined } | undefined,\n key: T,\n): z.infer<AnnotationJson[T]> | undefined {\n return readMetadataJsonOrThrow<Annotation, T>(\n spec?.annotations,\n AnnotationJson,\n key,\n \"readAnnotationJsonOrThrow\",\n );\n}\n\n/// Helper function for reading json-encoded annotation values, returns undefined on JSON parsing error\nexport function readAnnotationJson<T extends keyof AnnotationJson>(\n spec: { annotations?: Metadata | undefined } | undefined,\n key: T,\n): z.infer<AnnotationJson[T]> | undefined {\n return readMetadataJson<Annotation, T>(spec?.annotations, AnnotationJson, key);\n}\n\nexport function isLinkerColumn(column: PColumnSpec): boolean {\n return !!readAnnotationJson(column, Annotation.IsLinkerColumn);\n}\n\n/**\n * Specification of an individual axis.\n *\n * Each axis is a part of a composite key that addresses data inside the PColumn.\n *\n * Each record inside a PColumn is addressed by a unique tuple of values set for\n * all the axes specified in the column spec.\n */\nexport type AxisSpec = {\n /** Type of the axis value. Should not use non-key types like float or double. */\n readonly type: AxisValueType;\n\n /** Name of the axis */\n readonly name: string;\n\n /** Adds auxiliary information to the axis name, type and parents to form a\n * unique identifier */\n readonly domain?: Record<string, string>;\n\n /** Context domain provides additional axis identity that is matched\n * by kinship rules (subset/superset/overlap) rather than exact equality */\n readonly contextDomain?: Record<string, string>;\n\n /** Any additional information attached to the axis that does not affect its\n * identifier */\n readonly annotations?: Record<string, string>;\n\n /**\n * Parent axes provide contextual grouping for the axis in question, establishing\n * a hierarchy where the current axis is dependent on one or more axes for its\n * full definition and meaning. For instance, in a data structure where each\n * \"container\" axis may contain multiple \"item\" axes, the `item` axis would\n * list the index of the `container` axis in this field to denote its dependency.\n *\n * This means that the identity or significance of the `item` axis is only\n * interpretable when combined with its parent `container` axis. An `item` axis\n * index by itself may be non-unique and only gains uniqueness within the context\n * of its parent `container`. Therefore, the `parentAxes` field is essential for\n * mapping these relationships and ensuring data coherence across nested or\n * multi-level data models.\n *\n * A list of zero-based indices of parent axes in the overall axes specification\n * from the column spec. Each index corresponds to the position of a parent axis\n * in the list that defines the structure of the data model.\n */\n readonly parentAxes?: number[];\n};\n\n/** Parents are specs, not indexes; normalized axis can be used considering its parents independently from column */\nexport interface AxisSpecNormalized extends Omit<AxisSpec, \"parentAxes\"> {\n parentAxesSpec: AxisSpecNormalized[];\n}\n\n/** Tree: axis is a root, its parents are children */\nexport type AxisTree = {\n axis: AxisSpecNormalized;\n children: AxisTree[]; // parents\n};\n\nfunction makeAxisTree(axis: AxisSpecNormalized): AxisTree {\n return { axis, children: [] };\n}\n\n/** Build tree by axis parents annotations */\nexport function getAxesTree(rootAxis: AxisSpecNormalized): AxisTree {\n const root = makeAxisTree(rootAxis);\n let nodesQ = [root];\n while (nodesQ.length) {\n const nextNodes: AxisTree[] = [];\n for (const node of nodesQ) {\n node.children = node.axis.parentAxesSpec.map(makeAxisTree);\n nextNodes.push(...node.children);\n }\n nodesQ = nextNodes;\n }\n return root;\n}\n\n/** Get set of canonicalized axisIds from axisTree */\nexport function getSetFromAxisTree(tree: AxisTree): Set<CanonicalizedJson<AxisId>> {\n const set = new Set([canonicalizeJson(getAxisId(tree.axis))]);\n let nodesQ = [tree];\n while (nodesQ.length) {\n const nextNodes = [];\n for (const node of nodesQ) {\n for (const parent of node.children) {\n set.add(canonicalizeJson(getAxisId(parent.axis)));\n nextNodes.push(parent);\n }\n }\n nodesQ = nextNodes;\n }\n return set;\n}\n\n/** Get array of axisSpecs from axisTree */\nexport function getArrayFromAxisTree(tree: AxisTree): AxisSpecNormalized[] {\n const res = [tree.axis];\n let nodesQ = [tree];\n while (nodesQ.length) {\n const nextNodes = [];\n for (const node of nodesQ) {\n for (const parent of node.children) {\n res.push(parent.axis);\n nextNodes.push(parent);\n }\n }\n nodesQ = nextNodes;\n }\n return res;\n}\n\nexport function canonicalizeAxisWithParents(axis: AxisSpecNormalized) {\n return canonicalizeJson(getArrayFromAxisTree(getAxesTree(axis)).map(getAxisId));\n}\n\nfunction normalizingAxesComparator(\n axis1: AxisSpecNormalized,\n axis2: AxisSpecNormalized,\n): 1 | -1 | 0 {\n if (axis1.name !== axis2.name) {\n return axis1.name < axis2.name ? 1 : -1;\n }\n if (axis1.type !== axis2.type) {\n return axis1.type < axis2.type ? 1 : -1;\n }\n const domain1 = canonicalizeJson(axis1.domain ?? {});\n const domain2 = canonicalizeJson(axis2.domain ?? {});\n if (domain1 !== domain2) {\n return domain1 < domain2 ? 1 : -1;\n }\n\n const contextDomain1 = canonicalizeJson(axis1.contextDomain ?? {});\n const contextDomain2 = canonicalizeJson(axis2.contextDomain ?? {});\n if (contextDomain1 !== contextDomain2) {\n return contextDomain1 < contextDomain2 ? 1 : -1;\n }\n\n const parents1 = canonicalizeAxisWithParents(axis1);\n const parents2 = canonicalizeAxisWithParents(axis2);\n\n if (parents1 !== parents2) {\n return parents1 < parents2 ? 1 : -1;\n }\n\n const annotation1 = canonicalizeJson(axis1.annotations ?? {});\n const annotation2 = canonicalizeJson(axis2.annotations ?? {});\n if (annotation1 !== annotation2) {\n return annotation1 < annotation2 ? 1 : -1;\n }\n return 0;\n}\n\nfunction parseParentsFromAnnotations(axis: AxisSpec) {\n const parentsList = readAnnotationJson(axis, Annotation.Parents);\n if (parentsList === undefined) {\n return [];\n }\n return parentsList;\n}\n\nfunction sortParentsDeep(axisSpec: AxisSpecNormalized) {\n axisSpec.parentAxesSpec.forEach(sortParentsDeep);\n axisSpec.parentAxesSpec.sort(normalizingAxesComparator);\n}\n\nfunction hasCycleOfParents(axisSpec: AxisSpecNormalized) {\n const root = makeAxisTree(axisSpec);\n let nodesQ = [root];\n const ancestors = new Set(canonicalizeJson(getAxisId(axisSpec)));\n while (nodesQ.length) {\n const nextNodes: AxisTree[] = [];\n const levelIds = new Set<CanonicalizedJson<AxisId>>();\n for (const node of nodesQ) {\n node.children = node.axis.parentAxesSpec.map(makeAxisTree);\n for (const child of node.children) {\n const childId = canonicalizeJson(getAxisId(child.axis));\n if (!levelIds.has(childId)) {\n nextNodes.push(child);\n levelIds.add(childId);\n if (ancestors.has(childId)) {\n return true;\n }\n ancestors.add(childId);\n }\n }\n }\n nodesQ = nextNodes;\n }\n return false;\n}\n\n/** Create list of normalized axisSpec (parents are in array of specs, not indexes) */\nexport function getNormalizedAxesList(axes: AxisSpec[]): AxisSpecNormalized[] {\n if (!axes.length) {\n return [];\n }\n const modifiedAxes: AxisSpecNormalized[] = axes.map((axis) => {\n const { parentAxes: _, ...copiedRest } = axis;\n return { ...copiedRest, annotations: { ...copiedRest.annotations }, parentAxesSpec: [] };\n });\n\n axes.forEach((axis, idx) => {\n const modifiedAxis = modifiedAxes[idx];\n if (axis.parentAxes) {\n // if we have parents by indexes then take from the list\n modifiedAxis.parentAxesSpec = axis.parentAxes.map((idx) => modifiedAxes[idx]);\n } else {\n // else try to parse from annotation name\n const parents = parseParentsFromAnnotations(axis).map((name) =>\n modifiedAxes.find((axis) => axis.name === name),\n );\n modifiedAxis.parentAxesSpec = parents.some((p) => p === undefined)\n ? []\n : (parents as AxisSpecNormalized[]);\n }\n });\n\n if (modifiedAxes.some(hasCycleOfParents)) {\n // Axes list is broken\n modifiedAxes.forEach((axis) => {\n axis.parentAxesSpec = [];\n });\n } else {\n modifiedAxes.forEach((axis) => {\n sortParentsDeep(axis);\n });\n }\n\n return modifiedAxes;\n}\n\n/** Create list of regular axisSpec from normalized (parents are indexes, inside of current axes list) */\nexport function getDenormalizedAxesList(axesSpec: AxisSpecNormalized[]): AxisSpec[] {\n const idsList = axesSpec.map(canonicalizeAxisId);\n return axesSpec.map((axisSpec) => {\n const parentsIds = axisSpec.parentAxesSpec.map(canonicalizeAxisId);\n const parentIdxs = parentsIds.map((id) => idsList.indexOf(id));\n const { parentAxesSpec: _, ...copiedRest } = axisSpec;\n if (parentIdxs.length) {\n return { ...copiedRest, parentAxes: parentIdxs } as AxisSpec;\n }\n return copiedRest;\n });\n}\n\n/**\n * Resolve annotation-based parents (`pl7.app/parents`) to numeric `parentAxes`\n * on a column spec. Returns the spec unchanged if all axes already use numeric\n * indices or have no parent annotations.\n */\nexport function resolveAnnotationParents(spec: PColumnSpec): PColumnSpec {\n const hasAnnotationParents = spec.axesSpec.some(\n (axis) => !!readAnnotationJson(axis, Annotation.Parents),\n );\n if (!hasAnnotationParents) return spec;\n\n const normalized = getNormalizedAxesList(spec.axesSpec);\n const denormalized = getDenormalizedAxesList(normalized);\n return { ...spec, axesSpec: denormalized };\n}\n\n/** Common type representing spec for all the axes in a column */\nexport type AxesSpec = AxisSpec[];\n\n/// Well-known column names\nexport const PColumnName = {\n Label: \"pl7.app/label\",\n Table: {\n RowSelection: \"pl7.app/table/row-selection\",\n },\n VDJ: {\n LeadSelection: \"pl7.app/vdj/lead-selection\",\n RankingOrder: \"pl7.app/vdj/ranking-order\",\n Sequence: \"pl7.app/vdj/sequence\",\n },\n} as const;\n\n/// Well-known axis names\nexport const PAxisName = {\n SampleId: \"pl7.app/sampleId\",\n VDJ: {\n Assay: {\n SequenceId: \"pl7.app/vdj/assay/sequenceId\",\n },\n ClusterId: \"pl7.app/vdj/clusterId\",\n ClonotypeKey: \"pl7.app/vdj/clonotypeKey\",\n ScClonotypeKey: \"pl7.app/vdj/scClonotypeKey\",\n },\n} as const;\n\nexport function isLabelColumn(column: PColumnSpec) {\n return column.axesSpec.length === 1 && column.name === PColumnName.Label;\n}\n\n/**\n * Full column specification including all axes specs and specs of the column\n * itself.\n *\n * A PColumn in its essence represents a mapping from a fixed size, explicitly\n * typed tuple to an explicitly typed value.\n *\n * (axis1Value1, axis2Value1, ...) -> columnValue\n *\n * Each element in tuple correspond to the axis having the same index in axesSpec.\n */\nexport type PUniversalColumnSpec = PObjectSpec & {\n /** Defines specific type of BObject, the most generic type of unit of\n * information in Platforma Project. */\n readonly kind: \"PColumn\";\n\n /** Type of column values */\n readonly valueType: string;\n\n /** Column name */\n readonly name: string;\n\n /** Adds auxiliary information to the axis name, type and parents to form a\n * unique identifier */\n readonly domain?: Record<string, string>;\n\n /** Context domain provides additional column identity that is matched\n * by kinship rules (subset/superset/overlap) rather than exact equality */\n readonly contextDomain?: Record<string, string>;\n\n /** Any additional information attached to the column that does not affect its\n * identifier */\n readonly annotations?: Record<string, string>;\n\n /** A list of zero-based indices of parent axes from the {@link axesSpec} array. */\n readonly parentAxes?: number[];\n\n /** Axes specifications */\n readonly axesSpec: AxesSpec;\n};\n\n/**\n * Specification of a data column.\n *\n * Data column is a specialized type of PColumn that stores only simple values (strings and numbers)\n * addressed by multiple keys. This is in contrast to other PColumn variants that can store more complex\n * values like files or other abstract data types. Data columns are optimized for storing and processing\n * basic tabular data.\n */\nexport type PDataColumnSpec = PUniversalColumnSpec & {\n /** Type of column values */\n readonly valueType: ValueType;\n};\n\n// @todo: change this to PUniversalColumnSpec\nexport type PColumnSpec = PDataColumnSpec;\n\n/** Unique PColumnSpec identifier */\nexport type PColumnSpecId = {\n /** Defines specific type of BObject, the most generic type of unit of\n * information in Platforma Project. */\n readonly kind: \"PColumn\";\n\n /** Type of column values */\n readonly valueType: ValueType;\n\n /** Column name */\n readonly name: string;\n\n /** Adds auxiliary information to the axis name, type and parents to form a\n * unique identifier */\n readonly domain?: Record<string, string>;\n\n /** Context domain provides additional column identity that is matched\n * by kinship rules (subset/superset/overlap) rather than exact equality */\n readonly contextDomain?: Record<string, string>;\n\n /** A list of zero-based indices of parent axes from the {@link axesSpec} array. */\n readonly parentAxes?: number[];\n\n /** Axes id */\n readonly axesId: AxesId;\n};\n\nexport function getPColumnSpecId(spec: PColumnSpec): PColumnSpecId {\n return {\n kind: spec.kind,\n valueType: spec.valueType,\n name: spec.name,\n domain: spec.domain,\n contextDomain: spec.contextDomain,\n parentAxes: spec.parentAxes,\n axesId: getAxesId(spec.axesSpec),\n };\n}\n\nexport interface PColumn<Data> extends PObject<Data> {\n /** PColumn spec, allowing it to be found among other PObjects */\n readonly spec: PColumnSpec;\n}\n\nexport type PColumnLazy<T> = PColumn<() => T>;\n\n/** Columns in a PFrame also have internal identifier, this object represents\n * combination of specs and such id */\nexport interface PColumnIdAndSpec {\n /** Internal column id within the PFrame */\n readonly columnId: PObjectId;\n\n /** Column spec */\n readonly spec: PColumnSpec;\n}\n\n/** Get column id and spec from a column */\nexport function getColumnIdAndSpec<Data>(column: PColumn<Data>): PColumnIdAndSpec {\n return {\n columnId: column.id,\n spec: column.spec,\n };\n}\n\n/** Information returned by {@link PFrame.listColumns} method */\nexport interface PColumnInfo extends PColumnIdAndSpec {\n /** True if data was associated with this PColumn */\n readonly hasData: boolean;\n}\n\nexport interface AxisId {\n /** Type of the axis or column value. For an axis should not use non-key\n * types like float or double. */\n readonly type: AxisValueType;\n\n /** Name of the axis or column */\n readonly name: string;\n\n /** Adds auxiliary information to the axis or column name and type to form a\n * unique identifier */\n readonly domain?: Record<string, string>;\n\n /** Context domain provides additional axis identity that is matched\n * by kinship rules (subset/superset/overlap) rather than exact equality */\n readonly contextDomain?: Record<string, string>;\n}\n\n/** Array of axis ids */\nexport type AxesId = AxisId[];\n\n/** Extracts axis ids from axis spec */\nexport function getAxisId(spec: AxisSpec): AxisId {\n const { type, name, domain, contextDomain } = spec;\n const result: AxisId = { type, name };\n if (domain && Object.entries(domain).length > 0) {\n Object.assign(result, { domain });\n }\n if (contextDomain && Object.entries(contextDomain).length > 0) {\n Object.assign(result, { contextDomain });\n }\n return result;\n}\n\n/** Extracts axes ids from axes spec array from column spec */\nexport function getAxesId(spec: AxesSpec): AxesId {\n return spec.map(getAxisId);\n}\n\n/** Canonicalizes axis id */\nexport function canonicalizeAxisId(id: AxisId): CanonicalizedJson<AxisId> {\n return canonicalizeJson(getAxisId(id));\n}\n\n/** Returns true if all domains from query are found in target */\nfunction matchDomain(query?: Record<string, string>, target?: Record<string, string>) {\n if (query === undefined) return target === undefined;\n if (target === undefined) return true;\n for (const k in target) {\n if (query[k] !== target[k]) return false;\n }\n return true;\n}\n\n/** Returns whether \"match\" axis id is compatible with the \"query\" */\nexport function matchAxisId(query: AxisId, target: AxisId): boolean {\n return (\n query.name === target.name &&\n matchDomain(query.domain, target.domain) &&\n matchDomain(query.contextDomain, target.contextDomain)\n );\n}\n\nexport function getTypeFromPColumnOrAxisSpec(spec: PColumnSpec | AxisSpec): ValueType {\n return \"valueType\" in spec ? spec.valueType : spec.type;\n}\n\nexport function isAxisId(id: unknown): id is AxisId {\n return typeof id === \"object\" && id !== null && \"name\" in id && \"type\" in id;\n}\n"],"mappings":"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"}
@@ -76,6 +76,7 @@ declare const Annotation: {
76
76
  readonly IsScore: "pl7.app/isScore";
77
77
  readonly IsSubset: "pl7.app/isSubset";
78
78
  readonly Label: "pl7.app/label";
79
+ readonly LinkLabel: "pl7.app/linkLabel";
79
80
  readonly Max: "pl7.app/max";
80
81
  readonly Min: "pl7.app/min";
81
82
  readonly MultipliesBy: "pl7.app/multipliesBy";
@@ -140,9 +141,21 @@ type Annotation = Metadata & Partial<{
140
141
  [Annotation.Table.FontFamily]: string;
141
142
  [Annotation.Table.OrderPriority]: StringifiedJson<number>;
142
143
  [Annotation.Table.Visibility]: "hidden" | "optional" | (string & {});
143
- [Annotation.Trace]: StringifiedJson<Record<string, unknown>>;
144
+ [Annotation.Trace]: StringifiedJson<Trace>;
144
145
  [Annotation.VDJ.IsAssemblingFeature]: StringifiedJson<boolean>;
145
146
  }>;
147
+ declare const TraceEntrySchema: z.ZodObject<{
148
+ type: z.ZodString;
149
+ label: z.ZodString;
150
+ }, "strip", z.ZodUnknown, z.objectOutputType<{
151
+ type: z.ZodString;
152
+ label: z.ZodString;
153
+ }, z.ZodUnknown, "strip">, z.objectInputType<{
154
+ type: z.ZodString;
155
+ label: z.ZodString;
156
+ }, z.ZodUnknown, "strip">>;
157
+ type TraceEntry = z.infer<typeof TraceEntrySchema>;
158
+ type Trace = TraceEntry[];
146
159
  type AnnotationJson = MetadataJson<Annotation>;
147
160
  declare const AnnotationJson: AnnotationJson;
148
161
  declare function readAnnotation<T extends keyof Annotation>(spec: {
@@ -352,5 +365,5 @@ declare function matchAxisId(query: AxisId, target: AxisId): boolean;
352
365
  declare function getTypeFromPColumnOrAxisSpec(spec: PColumnSpec | AxisSpec): ValueType;
353
366
  declare function isAxisId(id: unknown): id is AxisId;
354
367
  //#endregion
355
- export { Annotation, AnnotationJson, AxesId, AxesSpec, AxisId, AxisSpec, AxisSpecNormalized, AxisTree, AxisValueType, ColumnValueType, Domain, DomainJson, Metadata, MetadataJson, PAxisName, PColumn, PColumnIdAndSpec, PColumnInfo, PColumnLazy, PColumnName, PColumnSpec, PColumnSpecId, PDataColumnSpec, PUniversalColumnSpec, ValueType, canonicalizeAxisId, canonicalizeAxisWithParents, getArrayFromAxisTree, getAxesId, getAxesTree, getAxisId, getColumnIdAndSpec, getDenormalizedAxesList, getNormalizedAxesList, getPColumnSpecId, getSetFromAxisTree, getTypeFromPColumnOrAxisSpec, isAxisId, isLabelColumn, isLinkerColumn, matchAxisId, readAnnotation, readAnnotationJson, readAnnotationJsonOrThrow, readDomain, readDomainJson, readDomainJsonOrThrow, readMetadata, readMetadataJson, readMetadataJsonOrThrow, resolveAnnotationParents };
368
+ export { Annotation, AnnotationJson, AxesId, AxesSpec, AxisId, AxisSpec, AxisSpecNormalized, AxisTree, AxisValueType, ColumnValueType, Domain, DomainJson, Metadata, MetadataJson, PAxisName, PColumn, PColumnIdAndSpec, PColumnInfo, PColumnLazy, PColumnName, PColumnSpec, PColumnSpecId, PDataColumnSpec, PUniversalColumnSpec, Trace, TraceEntry, ValueType, canonicalizeAxisId, canonicalizeAxisWithParents, getArrayFromAxisTree, getAxesId, getAxesTree, getAxisId, getColumnIdAndSpec, getDenormalizedAxesList, getNormalizedAxesList, getPColumnSpecId, getSetFromAxisTree, getTypeFromPColumnOrAxisSpec, isAxisId, isLabelColumn, isLinkerColumn, matchAxisId, readAnnotation, readAnnotationJson, readAnnotationJsonOrThrow, readDomain, readDomainJson, readDomainJsonOrThrow, readMetadata, readMetadataJson, readMetadataJsonOrThrow, resolveAnnotationParents };
356
369
  //# sourceMappingURL=spec.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"spec.d.ts","names":[],"sources":["../../../../src/drivers/pframe/spec/spec.ts"],"mappings":"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"}
1
+ {"version":3,"file":"spec.d.ts","names":[],"sources":["../../../../src/drivers/pframe/spec/spec.ts"],"mappings":"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"}
@@ -76,6 +76,7 @@ const Annotation = {
76
76
  IsScore: "pl7.app/isScore",
77
77
  IsSubset: "pl7.app/isSubset",
78
78
  Label: "pl7.app/label",
79
+ LinkLabel: "pl7.app/linkLabel",
79
80
  Max: "pl7.app/max",
80
81
  Min: "pl7.app/min",
81
82
  MultipliesBy: "pl7.app/multipliesBy",
@@ -99,6 +100,10 @@ const Annotation = {
99
100
  IsMainSequence: "pl7.app/vdj/isMainSequence"
100
101
  }
101
102
  };
103
+ const TraceEntrySchema = z.object({
104
+ type: z.string(),
105
+ label: z.string()
106
+ }).catchall(z.unknown());
102
107
  const ValueTypeSchema = z.enum([
103
108
  "Int",
104
109
  "Long",
@@ -138,7 +143,7 @@ const AnnotationJson = {
138
143
  [Annotation.Sequence.Annotation.Mapping]: z.record(z.string(), z.string()),
139
144
  [Annotation.Sequence.IsAnnotation]: z.boolean(),
140
145
  [Annotation.Table.OrderPriority]: z.number(),
141
- [Annotation.Trace]: z.record(z.string(), z.unknown()),
146
+ [Annotation.Trace]: z.array(TraceEntrySchema),
142
147
  [Annotation.VDJ.IsAssemblingFeature]: z.boolean()
143
148
  };
144
149
  function readAnnotation(spec, key) {
@@ -281,9 +286,9 @@ function getNormalizedAxesList(axes) {
281
286
  }
282
287
  /** Create list of regular axisSpec from normalized (parents are indexes, inside of current axes list) */
283
288
  function getDenormalizedAxesList(axesSpec) {
284
- const idsList = axesSpec.map((axisSpec) => canonicalizeJson(getAxisId(axisSpec)));
289
+ const idsList = axesSpec.map(canonicalizeAxisId);
285
290
  return axesSpec.map((axisSpec) => {
286
- const parentIdxs = axisSpec.parentAxesSpec.map((axisSpec) => canonicalizeJson(getAxisId(axisSpec))).map((id) => idsList.indexOf(id));
291
+ const parentIdxs = axisSpec.parentAxesSpec.map(canonicalizeAxisId).map((id) => idsList.indexOf(id));
287
292
  const { parentAxesSpec: _, ...copiedRest } = axisSpec;
288
293
  if (parentIdxs.length) return {
289
294
  ...copiedRest,