Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
nbbeeken committed Aug 17, 2021
1 parent 4f227cb commit 195e3b8
Showing 1 changed file with 19 additions and 10 deletions.
29 changes: 19 additions & 10 deletions src/cursor/abstract_cursor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export abstract class AbstractCursor<
/** @internal */
[kTopology]: Topology;
/** @internal */
[kTransform]?: (doc: TSchema) => Document;
[kTransform]?: (doc: TSchema) => TSchema;
/** @internal */
[kInitialized]: boolean;
/** @internal */
Expand Down Expand Up @@ -356,9 +356,7 @@ export abstract class AbstractCursor<
const internalDocs = this[kDocuments].splice(0, this[kDocuments].length);
for (let i = 0; i < internalDocs.length; ++i) {
try {
result = iterator(
(transform ? transform(internalDocs[i]) : internalDocs[i]) as TSchema // TODO(NODE-3283): Improve transform typing
);
result = iterator(transform ? transform(internalDocs[i]) : internalDocs[i]);
} catch (error) {
return done(error);
}
Expand Down Expand Up @@ -417,9 +415,9 @@ export abstract class AbstractCursor<
docs.push(doc);

// these do need to be transformed since they are copying the rest of the batch
const internalDocs = (transform
const internalDocs = transform
? this[kDocuments].splice(0, this[kDocuments].length).map(transform)
: this[kDocuments].splice(0, this[kDocuments].length)) as TSchema[]; // TODO(NODE-3283): Improve transform typing
: this[kDocuments].splice(0, this[kDocuments].length);

if (internalDocs) {
docs.push(...internalDocs);
Expand Down Expand Up @@ -473,13 +471,24 @@ export abstract class AbstractCursor<
*/
map<T = any>(transform: (doc: TSchema) => T): AbstractCursor<T> {
assertUninitialized(this);
const oldTransform = this[kTransform] as (doc: TSchema) => TSchema; // TODO(NODE-3283): Improve transform typing
const oldTransform = this[kTransform];

// There is a reason for all the casting seen below:
// This is the only place one can specify a transform, and we've decided the most convenient
// useful API is to have TS claim this function returns a brand new cursor
// So this function either explicitly `.map<{myId: Type}>(...)` or implicitly `.map((d) => ({myId: d._id}))`
// "creates" a cursor parametrized to that type.
// That means the "new" cursor will always transform to the cursor's schema,
// hence the type of kTransform is (d: TSchema) => TSchema
// The truth is that the argument to that function isn't the schema, but that no longer matters after this point in the code
// Only the return type does. Essentially there is a lie, and we bottle up the lie logic here.

if (oldTransform) {
this[kTransform] = doc => {
this[kTransform] = (((doc: TSchema) => {
return transform(oldTransform(doc));
};
}) as unknown) as (doc: TSchema) => TSchema;
} else {
this[kTransform] = transform;
this[kTransform] = (transform as unknown) as (doc: TSchema) => TSchema;
}

return (this as unknown) as AbstractCursor<T>;
Expand Down

0 comments on commit 195e3b8

Please sign in to comment.