Skip to content

Commit

Permalink
feat(reka): implement getComponentSlots()
Browse files Browse the repository at this point in the history
  • Loading branch information
prevwong committed Jun 10, 2024
1 parent 340a234 commit 30c9b3a
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/wise-points-teach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rekajs/core': patch
---

Implement getComponentSlots() to quickly get slots defined in a Reka Component
4 changes: 4 additions & 0 deletions packages/core/src/reka.ts
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,10 @@ export class Reka {
);
}

getComponentSlots(component: t.Component) {
return this.head.resolver.componentToSlotsMap.get(component) ?? [];
}

/**
* Create a new Reka instance
*/
Expand Down
79 changes: 78 additions & 1 deletion packages/core/src/resolver.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as t from '@rekajs/types';
import { invariant } from '@rekajs/utils';
import {
computed,
IComputedValue,
Expand Down Expand Up @@ -32,6 +33,8 @@ export class Resolver {
identifiersToIdentifiable: Map<t.Identifier, t.Identifiable>;
nodeToScope: Map<t.ASTNode, Scope>;

componentToSlotsMap: Map<t.Component, Map<string, Set<t.SlotTemplate>>>;

private scope: Scope;
private cachedComponentResolver: WeakMap<
t.Component,
Expand Down Expand Up @@ -61,9 +64,12 @@ export class Resolver {

this.nodeToScope = new Map();

this.componentToSlotsMap = new Map();

makeObservable(this, {
identifiersToIdentifiableDistance: observable,
nodeToScope: observable,
componentToSlotsMap: observable,
});
}

Expand Down Expand Up @@ -116,6 +122,58 @@ export class Resolver {
});
}

private bindSlotToComponent(component: t.Component, slot: t.SlotTemplate) {
runInAction(() => {
const componentMap = this.componentToSlotsMap.get(component);

//TODO: support named slots
const slotName = 'children';

if (!componentMap) {
this.componentToSlotsMap.set(
component,
new Map([[slotName, new Set([slot])]])
);

return;
}

const slotSet = componentMap.get(slotName);

if (!slotSet) {
componentMap.set(slotName, new Set([slot]));
return;
}

slotSet.add(slot);
});
}

private unbindSlotToComponent(slot: t.SlotTemplate) {
const scope = this.nodeToScope.get(slot);
const slotName = 'children';

if (!scope) {
return;
}

const componentScope = scope.context?.component;
if (!componentScope) {
return;
}

const component = this.reka.getNodeFromId(
componentScope.id,
t.RekaComponent
);

this.componentToSlotsMap.get(component)?.get(slotName)?.delete(slot);

if (this.componentToSlotsMap.get(component)?.get(slotName)?.size === 0) {
this.componentToSlotsMap.get(component)?.delete(slotName);
}
}

unbindIdentifierToIdentifiable(identifier: t.Identifier) {
runInAction(() => {
this.identifiersToIdentifiable.delete(identifier);
Expand Down Expand Up @@ -254,7 +312,7 @@ export class Resolver {
});

if (component.template) {
this.resolveTemplate(component.template, componentScope);
this.resolveTemplate(component.template, componentScope);
}
}),
key: scope.toString(),
Expand All @@ -276,6 +334,15 @@ export class Resolver {

this.bindNodeToScope(template, templateScope);

if (t.is(template, t.SlotTemplate)) {
const componentId = scope.context?.component.id;
invariant(componentId);

const component = this.reka.getNodeFromId(componentId, t.RekaComponent);

this.bindSlotToComponent(component, template);
}

let eachIndex: string | null = null;
let eachAliasName: string | null = null;

Expand Down Expand Up @@ -403,6 +470,16 @@ export class Resolver {
return;
}

if (t.is(node, t.Component)) {
runInAction(() => {
this.componentToSlotsMap.delete(node);
});
}

if (t.is(node, t.SlotTemplate)) {
this.unbindSlotToComponent(node);
}

const scopeId = getKeyFromScopeDescription(scopeDescription);

this.scopeRegistry.delete(scopeId);
Expand Down
15 changes: 15 additions & 0 deletions packages/core/src/scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,19 @@ export const getScopeDescriptionByNodeOwner = (
return description;
};

export type ScopeContext = {
component?: t.Component;
};

export class Scope {
identifiables: Map<string, t.Identifiable>;

description: ScopeDescription;

path: string;

context: Record<string, ScopeDescription> | null;

constructor(
readonly resolver: Resolver,
descriptionOrNode: ScopeDescription | t.ASTNode,
Expand All @@ -124,6 +130,15 @@ export class Scope {

this.resolver.scopeRegistry.set(this.key, this);

this.context = null;

if (parent) {
this.context = {
...(parent.context ?? {}),
[parent.description.level]: parent.description,
};
}

makeObservable(this, {
identifiables: observable,
defineIdentifiable: action,
Expand Down

0 comments on commit 30c9b3a

Please sign in to comment.