Skip to content

Commit

Permalink
Merge pull request #42 from VictorS67/serializable
Browse files Browse the repository at this point in the history
Adding `getAttribute()` to all serializable callables
  • Loading branch information
VictorS67 authored Feb 8, 2024
2 parents 631f90e + 421284a commit f392f76
Show file tree
Hide file tree
Showing 4 changed files with 949 additions and 3 deletions.
5 changes: 2 additions & 3 deletions packages/core/src/load/serializable.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { v4 as uuidv4 } from 'uuid';

import { shallowCopy } from '../utils/copy.js';
import { IdProvider } from '../utils/nanoid.js';
// import { nanoid } from 'nanoid';
import {
Expand Down Expand Up @@ -81,9 +82,7 @@ export type Serialized =
| SerializedNotImplemented
| SerializedRecord;

function shallowCopy<T extends object>(obj: T): T {
return Array.isArray(obj) ? ([...obj] as T) : ({ ...obj } as T);
}


export function safeAssign<T extends object>(target: T, source: T): T {
for (const key in source) {
Expand Down
140 changes: 140 additions & 0 deletions packages/core/src/record/callable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
SerializedInputRecord,
} from '../load/serializable.js';
import { AsyncCallError, AsyncCaller } from '../utils/asyncCaller.js';
import { shallowCopy } from '../utils/copy.js';
import { ReadableStreamAsyncIterable } from '../utils/stream.js';
import { convertCallableLikeToCallable, isValidLambdaFunc } from './utils.js';

Expand Down Expand Up @@ -107,6 +108,10 @@ export type CallableBatchOptions = {
returnExceptions?: boolean;
};

export type SerializedCallableFields = {
[key: string]: Callable | Record<string, Callable> | Array<Callable>;
};

/**
* Abstract class representing a callable. A callable is an object that can be
* "called" or invoked with an input to produce an output, potentially asynchronously.
Expand Down Expand Up @@ -388,6 +393,69 @@ export abstract class Callable<
});
}

protected _getCallableMetadata(): {
type: string;
callables?: SerializedCallableFields;
} {
return {
type: 'Callable',
};
}

protected _removeCallable(
root: SerializedFields,
callablesMap: SerializedCallableFields
): SerializedFields {
const result: SerializedFields = shallowCopy(root);

for (const [path, callable] of Object.entries(callablesMap)) {
const [last, ...partsReverse] = path.split('.').reverse();

let current: SerializedFields = result;
for (const key of partsReverse.reverse()) {
if (current[key] === undefined) {
break;
}

current[key] = shallowCopy(current[key] as SerializedFields);
current = current[key] as SerializedFields;
}

if (current[last] !== undefined) {
if (path.split('.').length > 1) {
delete result[path.split('.')[0]];
} else {
delete current[last];
}
}
}

return result;
}

getAttributes(): {
aliases: SerializedKeyAlias;
secrets: SecretFields;
kwargs: SerializedFields;
metadata: { type: string; callables?: SerializedCallableFields };
} {
const { aliases, secrets, kwargs } = super.getAttributes();

const metadata = this._getCallableMetadata();

const filteredKwargs =
metadata.callables && Object.keys(metadata.callables).length
? this._removeCallable(kwargs, metadata.callables)
: kwargs;

return {
aliases,
secrets,
kwargs: filteredKwargs,
metadata,
};
}

async toRecord(
outputs: CallOutput,
parent?: RecordId | undefined
Expand Down Expand Up @@ -607,6 +675,18 @@ export class CallableBind<
);
}

protected _getCallableMetadata(): {
type: string;
callables?: SerializedCallableFields;
} {
return {
type: 'CallableBind',
callables: {
bound: this.bound,
},
};
}

async toInputRecord(
aliases: SerializedKeyAlias,
secrets: SecretFields,
Expand Down Expand Up @@ -820,6 +900,15 @@ export class CallableLambda<CallInput, CallOutput> extends Callable<
): Promise<CallOutput> {
return this._callWithConfig(this._invoke, input, options);
}

protected _getCallableMetadata(): {
type: string;
callables?: SerializedCallableFields;
} {
return {
type: 'CallableLambda',
};
}
}

/**
Expand Down Expand Up @@ -897,6 +986,18 @@ export class CallableMap<CallInput> extends Callable<

return output;
}

protected _getCallableMetadata(): {
type: string;
callables?: SerializedCallableFields;
} {
return {
type: 'CallableMap',
callables: {
steps: this.steps,
},
};
}
}

/**
Expand Down Expand Up @@ -975,6 +1076,18 @@ export class CallableEach<
return this.bound.batch(inputs, options);
}

protected _getCallableMetadata(): {
type: string;
callables?: SerializedCallableFields;
} {
return {
type: 'CallableEach',
callables: {
bound: this.bound,
},
};
}

async toInputRecord(
aliases: SerializedKeyAlias,
secrets: SecretFields,
Expand Down Expand Up @@ -1195,6 +1308,19 @@ export class CallableWithFallbacks<CallInput, CallOutput> extends Callable<
throw firstError;
}

protected _getCallableMetadata(): {
type: string;
callables?: SerializedCallableFields;
} {
return {
type: 'CallableWithFallbacks',
callables: {
callable: this.callable,
fallbacks: this.fallbacks,
},
};
}

async toInputRecord(
aliases: SerializedKeyAlias,
secrets: SecretFields,
Expand Down Expand Up @@ -1485,4 +1611,18 @@ export class CallableSequence<
last: convertCallableLikeToCallable(callableLike),
});
}

protected _getCallableMetadata(): {
type: string;
callables?: SerializedCallableFields;
} {
return {
type: 'CallableSequence',
callables: {
first: this.first,
middle: this.middle,
last: this.last
},
};
}
}
Loading

0 comments on commit f392f76

Please sign in to comment.