Skip to content

Commit

Permalink
feat: selector builder and async reifier
Browse files Browse the repository at this point in the history
  • Loading branch information
tchardin committed Nov 30, 2022
1 parent 70f520f commit 25e5f10
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 4 deletions.
81 changes: 77 additions & 4 deletions src/traversal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ export type SelectorNode = {
// Sequence
":>"?: SelectorNode;
};
// ExploreInterpretAs
"~"?: {
// adl
as: string;
Expand All @@ -220,7 +221,7 @@ export type SelectorNode = {
"!"?: SelectorNode; // StopAt
};

type LimitNode = {
export type LimitNode = {
none?: {}; // LimitNone
depth?: number; // LimitDepth
};
Expand Down Expand Up @@ -255,6 +256,75 @@ export const entriesSelector: SelectorNode = {
},
};

export const selectorBuilder = {
depth(val: number): LimitNode {
return {
depth: val,
};
},
noLimit(): LimitNode {
return {
none: {},
};
},
exploreRecursive(next: SelectorNode, limit: LimitNode): SelectorNode {
return {
R: {
l: limit,
":>": next,
},
};
},
exploreAll(next: SelectorNode): SelectorNode {
return {
a: {
">": next,
},
};
},
edge(): SelectorNode {
return {
"@": {},
};
},
exploreFields(fields: {[key: string]: SelectorNode}): SelectorNode {
return {
f: {
"f>": fields,
},
};
},
exploreInterpretAs(name: string, next: SelectorNode): SelectorNode {
return {
"~": {
as: name,
">": next,
},
};
},
match(): SelectorNode {
return {
".": {},
};
},
matchSubset(from: number, to: number): SelectorNode {
return {
".": {
"[": from,
"]": to,
},
};
},
exploreIndex(index: number, next: SelectorNode): SelectorNode {
return {
i: {
i: index,
">": next,
},
};
},
};

export class PathSegment {
value: string | number;
constructor(value: string | number) {
Expand Down Expand Up @@ -570,11 +640,14 @@ async function* mapEntries(node: {
}
}

export type NodeReifier = (node: Node, loader: LinkLoader) => Node;
export type NodeReifier = (node: Node, loader: LinkLoader) => Promise<Node>;

export type KnownReifiers = {[key: string]: NodeReifier};

export function unixfsReifier(node: Node, loader: LinkLoader): Node {
export async function unixfsReifier(
node: Node,
loader: LinkLoader
): Promise<Node> {
if (
node.kind == Kind.Map &&
node.value.Data &&
Expand Down Expand Up @@ -619,7 +692,7 @@ export async function* walkBlocks(
if (sel instanceof ExploreInterpretAs) {
const reify = source.reifier(sel.adl);
if (reify) {
const rnd = reify(nd, source);
const rnd = await reify(nd, source);
const next = sel.explore(nd, new PathSegment(""));
if (next) {
sel = next;
Expand Down
35 changes: 35 additions & 0 deletions test/traversal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import {importer} from "ipfs-unixfs-importer";
import {
BasicNode,
allSelector,
entriesSelector,
parseContext,
LinkSystem,
walkBlocks,
ExploreRecursive,
unixfsReifier,
selectorBuilder as builder,
} from "../src/traversal.js";
import {unixfsPathSelector} from "../src/resolver.js";

Expand Down Expand Up @@ -190,4 +192,37 @@ describe("traversal", () => {
}
expect(i).to.equal(expected.length);
});

it("build a selector", () => {
const selector1 = builder.exploreRecursive(
builder.exploreAll(builder.edge()),
builder.noLimit()
);

expect(selector1).to.deep.equal(allSelector);

const selector2 = builder.exploreRecursive(
builder.exploreAll(builder.edge()),
builder.depth(1)
);

expect(selector2).to.deep.equal(entriesSelector);

const {selector: unixfsSelector} = unixfsPathSelector(
"bafybeiepvdqmdakhtwotvykxujrmt5fcq4xca5jmoo6wzxhjk3q3pqe4te/children/third"
);

const selector3 = builder.exploreInterpretAs(
"unixfs",
builder.exploreFields({
children: builder.exploreInterpretAs(
"unixfs",
builder.exploreFields({
third: selector1,
})
),
})
);
expect(selector3).to.deep.equal(unixfsSelector);
});
});

0 comments on commit 25e5f10

Please sign in to comment.