Skip to content

Commit

Permalink
wip (pl error)
Browse files Browse the repository at this point in the history
  • Loading branch information
dbolotin committed Sep 1, 2024
1 parent 05f5d6a commit 3b60d12
Show file tree
Hide file tree
Showing 14 changed files with 469 additions and 226 deletions.
64 changes: 64 additions & 0 deletions model/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import { z } from 'zod';
import { base32Encode } from './base32-encode';
import { PValueInt, TreeNodeAccessor } from '@milaboratory/sdk-ui';

/** Number of raw bytes in the PlId. */
export const PlIdBytes = 15;
Expand Down Expand Up @@ -33,3 +34,66 @@ export async function digestPlId(data: string): Promise<PlId> {
const bytes = await crypto.subtle.digest('SHA-256', encoder.encode(data));
return plId(new Uint8Array(bytes.slice(0, 15)));
}

export const ResourceMapResourceTypeName = 'PColumnData/ResourceMap';
export const ResourceMapResourcePartitionedTypeName = 'PColumnData/Partitioned/ResourceMap';

export type PColumnKey = (string | number)[];

export type PColumnResourceMapEntry<T> = {
key: PColumnKey;
value: T;
};

export type PColumnResourceMapData<T> = {
isComplete: boolean;
data: PColumnResourceMapEntry<T>[];
};

function populateResourceMapData<T>(
acc: TreeNodeAccessor | undefined,
resourceParser: (acc: TreeNodeAccessor) => T | undefined,
data: PColumnResourceMapEntry<T>[],
keyPrefix: PColumnKey = []
): boolean {
if (acc === undefined) return false;
switch (acc.resourceType.name) {
case ResourceMapResourceTypeName: {
let isComplete = acc.getInputsLocked();
for (const keyStr of acc.listInputFields()) {
const value = acc.resolve({ field: keyStr, assertFieldType: 'Input' });
if (value === undefined) isComplete = false;
else {
const key = [...keyPrefix, ...JSON.parse(keyStr)] as PColumnKey;
const converted = resourceParser(value);
if (converted === undefined) isComplete = false;
else data.push({ key, value: converted });
}
}
return isComplete;
}
case ResourceMapResourcePartitionedTypeName: {
let isComplete = acc.getInputsLocked();
for (const keyStr of acc.listInputFields()) {
const value = acc.resolve({ field: keyStr, assertFieldType: 'Input' });
if (value === undefined) isComplete = false;
else {
const key = [...keyPrefix, ...JSON.parse(keyStr)] as PColumnKey;
isComplete = isComplete && populateResourceMapData(value, resourceParser, data, key);
}
}
return isComplete;
}
default:
throw new Error(`Unknown resource type: ${acc.resourceType.name}`);
}
}

export function parseResourceMap<T>(
acc: TreeNodeAccessor | undefined,
resourceParser: (acc: TreeNodeAccessor) => T | undefined
): PColumnResourceMapData<NonNullable<T>> {
const data: PColumnResourceMapEntry<NonNullable<T>>[] = [];
const isComplete = populateResourceMapData(acc, resourceParser, data, []);
return { isComplete, data };
}
26 changes: 20 additions & 6 deletions model/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,48 @@ import {
type InferOutputsType
} from '@milaboratory/sdk-ui';
import { BlockArgs, BlockArgsValid } from './args';
import { parseResourceMap } from './helpers';

export const platforma = BlockModel.create<BlockArgs>('Heavy')

.initialArgs({})

.output('presets', (ctx) =>
ctx.precalc?.resolve({ field: 'presets', assertFieldType: 'Input' })?.getFileHandle()
ctx.prerun?.resolve({ field: 'presets', assertFieldType: 'Input' })?.getFileHandle()
)

.output('preset', (ctx) =>
ctx.precalc?.resolve({ field: 'preset', assertFieldType: 'Input' })?.getDataAsString()
ctx.prerun?.resolve({ field: 'preset', assertFieldType: 'Input' })?.getDataAsString()
)

.output('qc', (ctx) =>
ctx.outputs?.resolve({ field: 'qc', assertFieldType: 'Input' })?.getDataAsJson()
parseResourceMap(ctx.outputs?.resolve({ field: 'qc', assertFieldType: 'Input' }), (acc) =>
acc.getRemoteFileHandle()
)
)

.output('reports', (ctx) =>
parseResourceMap(ctx.outputs?.resolve({ field: 'reports', assertFieldType: 'Input' }), (acc) =>
acc.getRemoteFileHandle()
)
)

.output('clones', (ctx) =>
parseResourceMap(ctx.outputs?.resolve({ field: 'clones', assertFieldType: 'Input' }), (acc) =>
acc.listInputFields()
)
)

.output('inputOptions', (ctx) => {
const spectFromPool = ctx.resultPool
.getSpecsFromResultPool();
const spectFromPool = ctx.resultPool.getSpecsFromResultPool();
return ctx.resultPool
.getSpecsFromResultPool()
.entries.filter((v) => {
if (!isPColumnSpec(v.obj)) return false;
const domain = v.obj.domain;
return (
v.obj.name === 'pl7.app/sequencing/data' &&
((v.obj.valueType as string) === 'blob' || (v.obj.valueType as string) === 'file') &&
(v.obj.valueType as string) === 'File' &&
domain !== undefined &&
(domain['pl7.app/fileExtension'] === 'fastq' ||
domain['pl7.app/fileExtension'] === 'fastq.gz')
Expand Down
11 changes: 8 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,16 @@
"@milaboratory/tengo-sdk": "file:/Volumes/Data/Projects/MiLaboratory/blocks-beta/tengo-sdk/milaboratory-tengo-sdk-1.0.14.tgz",
"@milaboratory/tengo-template-builder": "file:/Volumes/Data/Projects/MiLaboratory/blocks-beta/tengo-template-builder"
}
},
"pnpm2": {
"overrides": {
"@milaboratory/tengo-sdk": "file:/Volumes/Data/Projects/MiLaboratory/blocks-beta/tengo-sdk",
"@milaboratory/pl-middle-layer": "file:/Volumes/Data/Projects/MiLaboratory/platforma/ts-pl-middle-layer",
"@milaboratory/sdk-ui": "file:/Volumes/Data/Projects/MiLaboratory/platforma/ts-sdk-ui"
}
}
},
"pnpm": {
"overrides": {
"@milaboratory/tengo-sdk": "file:/Volumes/Data/Projects/MiLaboratory/blocks-beta/tengo-sdk"
}
"overrides": {}
}
}
Loading

0 comments on commit 3b60d12

Please sign in to comment.