Skip to content

Commit

Permalink
feat: add a mechanism to retrieve all context (with defaults) (#1751)
Browse files Browse the repository at this point in the history
Previously, all users of constructs would have to know beforehand the keys in the context to expect, and use either `tryGetContext` or `getContext` to retrieve a specific key from context.

This provides a mechanism to get the full context of a node in the construct tree, with overridable defaults. 

The `getAllContext` method allows users to retrieve all context. The interface for `getContext` and `tryGetContext` remains unchanged. 

I have also fixed a small typo in the library.
  • Loading branch information
pwrmiller committed Oct 7, 2023
1 parent 80a94b5 commit 23df709
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
15 changes: 15 additions & 0 deletions API.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 20 additions & 1 deletion src/construct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class Node {
/**
* The id of this construct within the current scope.
*
* This is a a scope-unique id. To obtain an app-unique id for this construct, use `addr`.
* This is a scope-unique id. To obtain an app-unique id for this construct, use `addr`.
*/
public readonly id: string;

Expand Down Expand Up @@ -236,6 +236,25 @@ export class Node {
return this.scope && this.scope.node.getContext(key);
}

/**
* Retrieves the all context of a node from tree context.
*
* Context is usually initialized at the root, but can be overridden at any point in the tree.
*
* @param defaults Any keys to override the retrieved context
* @returns The context object or an empty object if there is discovered context
*/
public getAllContext(defaults?: object): any {
if (typeof defaults === 'undefined') {
defaults = {};
}

if (this.scope === undefined) { return defaults; }

const value = { ...this._context, ...defaults };
return this.scope && this.scope.node.getAllContext(value);
}

/**
* Retrieves a value from tree context.
*
Expand Down
16 changes: 16 additions & 0 deletions test/construct.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,22 @@ test('construct.getContext(key) throws if context is not defined', () => {
}).toThrowError(`No context value present for ${key} key`);
});

test('construct.getAllContext can be used to read the full context of a node', () => {
// GIVEN
const context = {
ctx1: 12,
ctx2: 'hello',
};

// WHEN
const t = createTree(context);
t.child1_1_1.node.setContext('ctx1', 13);

// THEN
expect(t.child1_2.node.getAllContext()).toStrictEqual(context);
expect(t.child1_1_1.node.getAllContext()).toStrictEqual({ ctx1: 13, ctx2: 'hello' });
});

test('construct.tryGetContext(key) can be used to read a value from context defined at the root level', () => {
const context = {
ctx1: 12,
Expand Down

0 comments on commit 23df709

Please sign in to comment.